省选模拟4

A. 图论题

简单斜率,从 \(S\) 跑一遍 再从 \(T\) 然后用斜率拼起来就行

Code
#include<bits/stdc++.h>
#define int long long
#define lson rt<<1
#define rson rt<<1|1
#define rint signed
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m,s,t,ans=inf;
int dis[200010];
int head[200010],ver[400010],to[400010],edge[400010],tot;
bool vis[200010];
struct E{int x,y,z;}e[400010];
inline void add(int x,int y,int z){ver[++tot]=y;edge[tot]=z;to[tot]=head[x];head[x]=tot;}
priority_queue<pair<int,int>>q;
inline void dij(int S){
	for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=0;
	dis[S]=0;q.push(make_pair(0,S));
	while(!q.empty()){
		int x=q.top().second;q.pop();if(vis[x]) continue;vis[x]=1;
		for(int i=head[x];i;i=to[i]){
			int y=ver[i];
			if(dis[y]>dis[x]+edge[i]){
				dis[y]=dis[x]+edge[i];
				q.push(make_pair(-dis[y],y));
			}
		}
	}
}
struct node{
	int k,b;
	inline int calc(int x){return k*x+b;}
}st[200010*4];
inline bool cover(node a,node b,int k){return b.calc(k)<=a.calc(k);}
void build(int rt,int l,int r){
	st[rt].k=0,st[rt].b=inf;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
}
void ins(int rt,int l,int r,node k){
	if(cover(st[rt],k,l)&&cover(st[rt],k,r)) return st[rt]=k,void();
	if(l==r) return ;
	int mid=(l+r)>>1;
	if(cover(st[rt],k,mid)) swap(st[rt],k);
	if(cover(st[rt],k,l)) ins(lson,l,mid,k);
	if(cover(st[rt],k,r)) ins(rson,mid+1,r,k);
}
int query(int rt,int l,int r,int pos){
	if(l==r) return st[rt].calc(pos);
	int mid=(l+r)>>1,res=st[rt].calc(pos);
	if(pos<=mid) res=min(res,query(lson,l,mid,pos));
	else res=min(res,query(rson,mid+1,r,pos));
	return res;
}
signed main(){
#ifdef LOCAL
	freopen("in","r",stdin);
	freopen("out","w",stdout);
#endif
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	n=read(),m=read(),s=read(),t=read();
	for(int i=1;i<=m;i++) e[i].x=read(),e[i].y=read(),e[i].z=read();
	for(int i=1;i<=m;i++) add(e[i].y,e[i].x,e[i].z);
	dij(t);build(1,1,n);
	for(int i=1;i<=n;i++) ins(1,1,n,(node){-2ll*i,dis[i]+i*i});
	memset(head,0,sizeof(head));tot=0;
	for(int i=1;i<=m;i++) add(e[i].x,e[i].y,e[i].z);
	dij(s);
	for(int i=1;i<=n;i++) ans=min(ans,dis[i]+i*i+query(1,1,n,i));
	printf("%lld\n",ans);
	return 0;
}

B. 构造题

不会

C. 数据结构题

posted @ 2022-01-21 19:02  Max_QAQ  阅读(53)  评论(0编辑  收藏  举报