传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2330
一直以为差分约束系统很神……然后学了它……
求最大值跑最短路,求最小值跑最长路(我也不知道为什么)
如果有x-y>=z 连边 y->x w = z (最长路) x->y w=-z (最短路)
超级源点连所有点w=0,这道题似乎是说每个人至少有一个糖果……所以此题源点的dis值是1
Code:
#include<cstdio> #include<cmath> #include<vector> #include<climits> #include<queue> #include<stack> #include<cstring> #include<iostream> #include<algorithm> #define V first #define W second using namespace std; const int maxn=1e5+10; typedef long long lld; typedef pair<lld,lld> pii; namespace TOPL{ vector<pii>G[maxn]; lld d[maxn]; lld in[maxn],vis[maxn]; void add(lld u,lld v,lld w){ G[u].push_back(pii(v,w)); }lld n,m; void init(){ scanf("%lld%lld",&n,&m); for(lld i=1;i<=m;i++){ lld opt;scanf("%lld",&opt); lld x,y;scanf("%lld%lld",&x,&y); switch(opt){ case 1:{ add(x,y,0); add(y,x,0); break; } case 2:{ add(x,y,1); break; } case 3:{ add(y,x,0); break; } case 4:{ add(y,x,1); break; } case 5:{ add(x,y,0); break; } } } for(lld i=1;i<=n;i++) add(0,i,0); } lld solve(){ init(); queue<lld>q; memset(d,0xaf,sizeof(d)); d[0]=1; q.push(0); while(!q.empty()){ lld u=q.front();q.pop();vis[u]=0; for(lld i=0;i<G[u].size();i++){ lld v=G[u][i].V,w=G[u][i].W; if(d[v]<d[u]+w){ d[v]=d[u]+w; if(!vis[v]){ vis[v]=1; q.push(v); in[v]++; if(in[v]>=100){ puts("-1"); return 0; } } } } } lld ans=0; for(int i=1;i<=n;i++) ans+=d[i]; cout<<ans<<endl; return 0; } } int main(){ // freopen("candy5.in","r",stdin); return TOPL::solve(); }