差分约束 即解决线性规划问题 如果xj-xi<=bk,则建立一条有向边(vi,vj)=w(bk),问题的解可用最短路求出,如果有负权回路则表示无解(因为总有一个条件满足不了),否则得到解是满足等号的解
负权回路定义:如果存在一个环(从某个点出发又回到自己的路径),而且这个环上所有权值之和是负数,那这就是一个负权环,也叫负权回路
负权回路定义:如果存在一个环(从某个点出发又回到自己的路径),而且这个环上所有权值之和是负数,那这就是一个负权环,也叫负权回路
存在负权回路的图是不能求两点间最短路的,因为只要在负权回路上不断兜圈子,所得的最短路长度可以任意小。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
#define MAX 1002
struct Data
{
int a,b,w;
};
vector<Data>vec;
int d[MAX];
int N,ML,MD;
void CreateGraph()
{
Data t;vec.clear();
for(int i=1;i<N;i++)
{
t.a=i+1;t.b=i;t.w=0;
vec.push_back(t);
}
for(int i=0;i<ML;i++)
{
scanf("%d%d%d",&t.a,&t.b,&t.w);
vec.push_back(t);
}
for(int i=0;i<MD;i++)
{
scanf("%d%d%d",&t.b,&t.a,&t.w);
t.w=-t.w;
vec.push_back(t);
}
}
bool Bellman_Ford()
{
for(int i=2;i<=N;i++)
d[i]=1<<30;
d[1]=0;
int len=vec.size();
for(int t=1;t<N;t++)
{
bool flag=true;
for(int i=0;i<len;i++)
if(d[vec[i].a]+vec[i].w<d[vec[i].b])
d[vec[i].b]=d[vec[i].a]+vec[i].w,flag=false;
if(flag) break;
}
for(int i=0;i<len;i++)
if(d[vec[i].a]+vec[i].w<d[vec[i].b])
return false;
return true;
}
int main()
{
while(~scanf("%d%d%d",&N,&ML,&MD))
{
CreateGraph();
if(Bellman_Ford())
{
if(d[N]==1<<30)
printf("-2\n");
else printf("%d\n",d[N]);
}
else printf("-1\n");
}
return 0;
}