分析:设每个人的糖果数量是a[i] 最终就是求a[n]-a[1]的最大值
然后给出m个关系 u,v,c 表示a[u]+c>=a[v] 就是a[v]-a[u]<=c
所以对于这种情况,按照u,v,c建单向边,一条从1到n的路径就是一个关于1和n的推广不等式a[n]-a[1]<=k(k为这条路的权)
所以找到所有不等式中最小k,就是求1到n的最短路,这就是差分约束
然后上代码:
#include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namespace std; typedef long long LL; const int N=3e4+5; const int INF=0x3f3f3f3f; struct Edge{ int v,w,next; bool operator<(const Edge &e)const{ return w>e.w; } }edge[N*5]; int head[N],tot,n,m,d[N]; void add(int u,int v,int w){ edge[tot].v=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } priority_queue<Edge>q; bool vis[N]; int dij(int s,int t){ for(int i=1;i<=n;++i)d[i]=INF,vis[i]=0; d[s]=0,q.push(Edge{s,0,0}); while(!q.empty()){ while(!q.empty()&&vis[q.top().v])q.pop(); if(q.empty())break; int u=q.top().v; q.pop(); vis[u]=1; for(int i=head[u];~i;i=edge[i].next){ int v=edge[i].v; if(!vis[v]&&d[v]>d[u]+edge[i].w){ d[v]=d[u]+edge[i].w; q.push(Edge{v,d[v],0}); } } } return d[t]; } int main(){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)),tot=0; for(int i=1;i<=m;++i){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } printf("%d ",dij(1,n)); return 0; }