题目的正解
很明显可以看出是差分约束系统的题目,1:如果A和B距离至多为D则建边A->B权值为D,2:距离至少为D则建边B->A权值为-D。然后最短路。若有负权环则输出-1,若无法到达点N则输出-2,否则直接输出1~N的距离即可。
代码
#include<cstdio> #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<queue> using namespace std; const int maxn=2002; const int inf=0x3f3f3f3f; struct { int pre,v,c; }edge[1000009]; int kk,head[maxn],ml,mn,dist[maxn],y[maxn],n; bool b[maxn]; void addedge(int u,int v,int c) { kk++;edge[kk].v=v;edge[kk].c=c;edge[kk].pre=head[u];head[u]=kk; } int main() { scanf("%d%d%d",&n,&ml,&mn); for (int i=1;i<=ml;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); addedge(a,b,c); } for (int i=1;i<=mn;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); addedge(b,a,-c); }//建图 bool k=true; queue<int> q; memset(dist,inf,sizeof(dist)); dist[1]=0;y[1]=1;b[1]=true; q.push(1); while (!q.empty()) { int r=q.front(); q.pop(); for (int i=head[r];i;i=edge[i].pre) { int vv=edge[i].v,cc=edge[i].c; if (dist[r]+cc<dist[vv]) { dist[vv]=dist[r]+cc; if (!b[vv]) { y[vv]++; if (y[vv]==n) //判断负环 { k=false; break; } b[vv]=true; q.push(vv); } } } if (!k) break; b[r]=false; } // spfa最短路 if (!k) printf("-1"); else if (dist[n]!=inf) printf("%d",dist[n]); else printf("-2"); return 0; }