bzoj 1731 [Usaco2005 dec]Layout 排队布局——差分约束
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1731
对差分约束理解更深。还发现美妙博客:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html
原来不是一定要有一个源点向每个点连0边。而且“不可到达”原来是那个意思。
UPD(过了一会儿): vis[ ]被自己蒟掉了……但好在spfa也可以看松弛次数!一直以为只能看入队次数。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define ll long long using namespace std; const int N=1005,M=2e4+5+N; int n,ml,md,hd[N],xnt,to[M],nxt[M],w[M],cnt[N]; ll dis[N]; bool vis[N]; queue<int> q; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); return fx?ret:-ret; } void add(int x,int y,int z) { to[++xnt]=y; nxt[xnt]=hd[x]; hd[x]=xnt; w[xnt]=z; } ll spfa() { memset(dis,0x3f,sizeof dis); dis[1]=0; cnt[1]=1; q.push(1); vis[1]=1; ll INF=dis[2]; while(q.size()) { int k=q.front(); q.pop(); vis[k]=0; for(int i=hd[k],v;i;i=nxt[i]) if(dis[v=to[i]]>dis[k]+w[i]) { dis[v]=dis[k]+w[i]; if(!vis[v]) { q.push(v);cnt[v]++; if(cnt[v]==n) return -1; } } } return dis[n]==INF?-2:dis[n]; } int main() { n=rdn(); ml=rdn(); md=rdn(); for(int i=1,u,v,z;i<=ml;i++) { u=rdn(); v=rdn(); z=rdn(); add(u,v,z); } for(int i=1,u,v,z;i<=md;i++) { u=rdn(); v=rdn(); z=rdn(); add(v,u,-z); } for(int i=2;i<=n;i++) add(i,i-1,0); printf("%lld\n",spfa()); return 0; }