果然,差分约束的构图才是最关键的步骤,spfa的过程基本已经很熟了,用队列实现的话
在加边的时候,理解错了,重复加边了,s[a]-s[b]>=c 跟s[b]-s[a]>=-c 有区别么?天啊,秀逗了,我来了俩个add(a,b,c),add(b,a,-c)………………
题目有三个判断条件,存在负环,则无解,dis[n]=MAXINT,则可以为任意距离
#include<iostream> #include<queue> #define MAXINT 9999999 #define MAXN 1010 using namespace std; int vis[MAXN],cou[MAXN],dis[MAXN],root[MAXN],n,num; struct edge { int u,w,next; }e[MAXN*20]; void add(int u,int v,int len) { e[num].u=v; e[num].w=len; e[num].next=root[u]; root[u]=num++; } bool spfa() { for(int i=1;i<=n;i++) dis[i]=MAXINT; dis[1]=0; memset(vis,0,sizeof(vis)); memset(cou,0,sizeof(cou)); vis[1]=cou[1]=1; queue<int> Q; Q.push(1); while(!Q.empty()) { int t=Q.front(),k; Q.pop();vis[t]=0; for(int j=root[t];j!=-1;j=e[j].next) { k=e[j].u; if(dis[k]>e[j].w+dis[t]) { dis[k]=e[j].w+dis[t]; if(!vis[k]) { vis[k]=1; Q.push(k); cou[k]++; if(cou[k]>n) return 0; } } } } return 1; } int main() { int m1,m2; int a,b,c; while(cin>>n>>m1>>m2) { memset(root,-1,sizeof(root)); num=0; for(int i=0;i<m1;i++) { cin>>a>>b>>c; add(a,b,c); } for(int i=0;i<m2;i++) { cin>>a>>b>>c; add(b,a,-c); } if(spfa()) { if(dis[n]!=MAXINT) cout<<dis[n]<<endl; else cout<<-2<<endl; } else cout<<-1<<endl; } return 0; }