题解:SPFA裸题,首先计算出最短距离然后乱搞即可
#include<stdio.h> #include<queue> #include<math.h> #define max(a,b) ((a)>(b)?(a):(b)) #define abs(t) ((t)>0?(t):(-(t))) using namespace std; const int N=1000001; struct edge{int next,to,len;} e[N]; queue<int> q;typedef long long ll; int n,g[N],a[N],b[N],c[N],d[N],u[N],M,m; ll dis[N],ans=0,t;bool inq[N]; inline void addedge(int x,int y,int z){e[++M]=(edge){g[x],y,z};g[x]=M;} int main(){ freopen("purify.in","r",stdin);freopen("purify.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1,x;i<=n;i++){ scanf("%d",&x); if(x==1){q.push(i);dis[i]=0;inq[i]=true;} else dis[i]=(1ll<<50); } for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]); if(c[i]==1) addedge(a[i],b[i],d[i]); else{addedge(a[i],b[i],d[i]);addedge(b[i],a[i],d[i]);} } while(!q.empty()){ register int h=q.front();q.pop();inq[h]=false; for(register int i=g[h];i;i=e[i].next) if(dis[e[i].to]>dis[h]+e[i].len){ dis[e[i].to]=dis[h]+e[i].len; if(!inq[e[i].to]){q.push(e[i].to);inq[e[i].to]=true;} } } for(register int i=1,x,y;i<=m;i++){ x=a[i];y=b[i]; if(c[i]==1) ans=max(ans,dis[x]+d[i]); else{ t=dis[x]-dis[y]; if(abs(t)>d[i]) ans=max(ans,max(dis[x],dis[y])); else ans=max(ans,ceil(max((-t+d[i])/2.0+dis[x],(t+d[i])/2.0+dis[y]))); } } printf("%I64d ",ans); return 0; }
【我保证以后不恶意压行了!】