题目的正解
很明显可以看出是差分约束系统的题目,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;
}