题目大意
n个人分糖果 其中i要求j不能比他的糖果数多c个 求第一个人的糖果数与第n个人的糖果数差最大
题解
由题目可知
cnt[j]-cnt[i]≤c 变形--cnt[j]≤cnt[[i]+c
这个式子像是单源最短路问题上的松弛操作...
因为c是大于等于0的 不会出现负环 在没有负环的
图上spfa的栈实现是比队列实现效率高的(涨姿势..
而且spfa的dfs判环是比bfs判环效率高的,上题可知(玄学
然后建图 跑spfa 图不连通无解
代码
#include<iostream> #include<stack> #include<cstdio> #include<cstring> #define mxn 30003 #define mxe 150009 using namespace std; int n,m,a,b,c,sumedge; int head[mxn],vis[mxn],dis[mxn]; struct Edge{ int x,y,z,nxt; Edge(int x=0,int y=0,int z=0,int nxt=0): x(x),y(y),z(z),nxt(nxt){} }edge[mxe]; void add(int x,int y,int z){ edge[++sumedge]=Edge(x,y,z,head[x]); head[x]=sumedge; } void spfa(){ dis[1]=0;stack<int>q; q.push(1); while(q.size()){ int now=q.top();q.pop();vis[now]=0; for(int i=head[now];i;i=edge[i].nxt){ int v=edge[i].y; if(dis[v]>dis[now]+edge[i].z){ dis[v]=dis[now]+edge[i].z; if(vis[v]==0){vis[v]=1;q.push(v);} } } } } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ memset(vis,0,sizeof(vis)); memset(head,0,sizeof(head)); memset(dis,0x3f,sizeof(dis)); sumedge=0; for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c); } spfa(); printf("%d ",dis[n]); } return 0; }