多校省选模拟4

T1 图论题

从 s 和 t 分别跑个最短路,然后建出到 s 的凸包,用 t 二分去就行了

从 s 跑 k 次同时维护李超树可以求出连 k 条边的最优解

T2 构造题

没想懂细节

T3 数据结构题

因为是顺序改题,就没有然后了,,,

代码

T1

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
const int N=200011;
const int inf=1e18;
struct bag_{int x,y;friend bool operator<(bag_ a,bag_ b){return a.x!=b.x?a.x<b.x:a.y>b.y;}}now;
struct e_{int v,w;friend bool operator<(e_ a,e_ b){return a.w>b.w;}};
bool jud[N];
int n,m,s,t;
int d[2][N];
vector<e_> v[2][N];
vector<bag_> bag;
priority_queue<e_> dui;
il int min_(int x,int y){return x>y?y:x;}
il double get_xl(bag_ a,bag_ b){return (b.y-a.y)/(b.x-a.x);}
il bool jd(bag_ a,bag_ b,bag_ c){return (b.x==c.x)||get_xl(a,c)>=get_xl(b,c);}
il int get_ans(bag_ a,int x){return x*x+a.y-2*a.x*x;}
il int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')ch=getchar();
	while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
	return s;
}
void dij(int x,bool jd)
{
	memset(d[jd],0x3f,sizeof(d[jd]));
	memset(jud,0,sizeof(jud));
	d[jd][x]=0;
	dui.push({x,0});
	e_ u;
	while(dui.size())
	{
		u=dui.top(),dui.pop();
		if(jud[u.v]) continue;
		jud[u.v]=1;
		for(e_ y : v[jd][u.v])
			if(d[jd][y.v]>d[jd][u.v]+y.w)
			{
				d[jd][y.v]=d[jd][u.v]+y.w;
				dui.push({y.v,d[jd][y.v]});
			}
	}
	return;
}
int two(int x)
{
	int sz=bag.size();
	if(sz==0) return inf;
	if(sz==1) return get_ans(bag[0],x);
	if(sz==2) return min_(get_ans(bag[0],x),get_ans(bag[1],x));
	if(get_ans(bag[0],x)<get_ans(bag[1],x)) return get_ans(bag[0],x);
	if(get_ans(bag[sz-1],x)<get_ans(bag[sz-2],x)) return get_ans(bag[sz-1],x);
	int l=1,r=sz-2,mid=1,ans=inf,ansl,ansr;
	while(l<=r)
	{
		mid=(l+r)>>1;
		ansl=get_ans(bag[mid],x);
		ansr=get_ans(bag[mid+1],x);
		if(ansl<ansr) r=mid-1;
		else l=mid+1;
		ans=min_(ans,min_(ansl,ansr));
	}
	ans=min_(ans,get_ans(bag[mid],x));
	ansl=get_ans(bag[mid-1],x);
	ansr=get_ans(bag[mid+1],x);
	return min_(ans,min_(ansl,ansr));
}
signed main()
{
//	freopen("c.in","r",stdin);
//	freopen("zj1.out","w",stdout);
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	n=read(),m=read(),s=read(),t=read();
	for(int x,y,z,i=1;i<=m;++i)
	{
		x=read(),y=read(),z=read();
		v[0][x].push_back({y,z});
		v[1][y].push_back({x,z});
	}
	dij(s,0),dij(t,1);
	int sz=0;
	for(int y,x,i=1;i<=n;++i)
	{
		if(d[1][i]==0x3f3f3f3f3f3f3f3f)continue;
		x=i,y=d[1][i]+i*i;
		now=(bag_){x,y};
		while(sz>1&&jd(bag[sz-2],bag[sz-1],now)) --sz,bag.pop_back();
		bag.push_back(now),++sz;
	}
	int ans=inf;
	for(int i=1;i<=n;++i) ans=min_(ans,d[0][i]+two(i));
	cout<<ans<<endl;
	return 0;
}
上一篇:篇7-UVM ERROR达到一定数量时结束仿真


下一篇:幻宇树莓派麦克纳姆轮小车:ROS层PID参数可视化调节