poj1201(差分约束)
题很水。。。但我被坑惨了
。。。。。。。。
。。。。。.。。。。。
。。。。。。。
构成差分约束系统时,1.如果在所有点外添加一个超级源0号点,并使得超级源到所有其他点的距离为0,那么最终求出的0号点到其他所有原始点的最短距离就是本系统的一个可行解,且可行解之间的差距最小. 2.如果初始时不添加超级源,只是将原始点的初始距离设为INF,且令其中一个原始点的初始距离为0,然后求该点到其他所有点的最短距离,那么最短距离的集合就是一个可行解,且该可行解两两之间的差距最大.注意方案2只能在该问题一定存在解的时候即肯定不存在负权环的时候用.否则从1号点到其他点没有路,但是其他点的强连通分量中有负权环,这样根本探测不到错误) 所以我们需要采取方案1.
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int maxn=50000+10; const int maxm=500000+10; const int nil=1e9; struct my{ int next; int v; int w; }; queue<int>Q; int maxx=-1; int adj[maxn],fa,n,m,d[maxn],inq[maxn]; my bian[maxm]; void myinsert(int u,int v,int w){ bian[++fa].v=v; bian[fa].next=adj[u]; bian[fa].w=w; adj[u]=fa; } int spfa(int s){ for (int i=0;i<=maxx;i++) d[i]=nil; d[s]=0; Q.push(s); inq[s]=true; while(!Q.empty()){ int u=Q.front();Q.pop(); inq[u]=false; for (int i=adj[u];i!=-1;i=bian[i].next){ int v=bian[i].v; if(d[v]>d[u]+bian[i].w){ d[v]=d[u]+bian[i].w; if(!inq[v]){ Q.push(v); inq[v]=true; } } } } return d[maxx]-d[9]; } int main(){ memset(adj,-1,sizeof(adj)); memset(bian,-1,sizeof(bian)); scanf("%d",&m); int u,v,w; for (int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); u+=10; v+=10; maxx=max(maxx,v); myinsert(v,u-1,-w); } for (int i=10;i<=maxx;i++){ myinsert(i,i-1,0); myinsert(i-1,i,1); myinsert(0,i,0); } myinsert(0,9,0); printf("%d\n",spfa(0)); return 0; }