省选模拟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. 数据结构题
咕