题意:n个人,m个信息,每行的信息是3个数字,A,B,C,表示B比A多出来的糖果不超过C个,问你,n号人最多比1号人多几个糖果
解题关键:差分约束系统转化为最短路,B-A>=C,建有向边即可,与dijkstra中的d[v]>=d[u]+C相同,即可求解。
最小值用最长路,最大值用最短路。
技巧:有一个超级源点向所有点连边,来固定每个点的约束。
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> #include<queue> #define max_v 32000 #define maxm 152000 #define inf 0x3f3f3f3f using namespace std; typedef long long ll; int head[max_v],tot; struct edge{ int to,w,nxt; }e[maxm]; void add_edge(int u,int v,int w){ e[tot].w=w; e[tot].to=v; e[tot].nxt=head[u]; head[u]=tot++; } typedef pair<int,int> P; int V,n,m,a,b,c,d[max_v]; void dijkstra(int s){ priority_queue<P,vector<P>,greater<P> >que; fill(d,d+V+1,inf); d[s]=0; que.push(P(0,s)); while(que.size()){ P p=que.top(); que.pop(); int v=p.second; if(d[v]<p.first) continue; for(int i=head[v];i!=-1;i=e[i].nxt){ edge ex=e[i]; if(d[ex.to]>d[v]+ex.w){ d[ex.to]=d[v]+ex.w; que.push(P(d[ex.to],ex.to)); } } } } int main(){ memset(head,-1,sizeof head); scanf("%d%d",&n,&m); V=n; for(int i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); } dijkstra(1); printf("%d ",d[n]); return 0; }