此题由于图可能不联通,要用spfa,就需要增设源点来先判断是否存在负环。
然后要去掉负环,重新spfa求解
//对诸如A-B>=C的形式,我们从A向B连一条有向边,权值为 -C。
//最小Ans应该是那个图 从顶点Vn 到顶点 V0 的最小距离(是负数,注意abs或加-)
//最大Ans应该是那个图 从顶点V0 到顶点 Vn 的最小距离(是正数)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
#define INF 1000000007
#define N 1005
#define M 45005
int n,m1,m2,o,o1;
int head[N],d[N],vv[N],tr[N];
bool v[N];
struct edge{
int to,next,w;
}e[M];
void add(int x,int y,int z)
{ e[o].to=y;
e[o].w=z;
e[o].next=head[x];
head[x]=o++;
}
bool spfa(int s,int tot)//第一次spfa,判断结果是否是-1
{ for (int i=0;i<=tot;i++)
d[i]=INF;
memset(v,0,sizeof(v));
memset(vv,0,sizeof(vv));
int hea=0,tail=1,now;
d[s]=0; tr[1]=s; v[s]=1; vv[s]++;
while (hea!=tail)
{
hea=(hea+1)%N;
now=tr[hea];
v[now]=0;
for (int k=head[now];k!=-1;k=e[k].next)
if (d[now]+e[k].w<d[e[k].to])
{d[e[k].to]=d[now]+e[k].w;
if (!v[e[k].to])
{
tail=(tail+1)%N;
tr[tail]=e[k].to;
vv[e[k].to]++;
v[e[k].to]=1;
if (vv[e[k].to]>tot) return 0;
}
}
}
return 1;
}
bool spfa2(int s,int tot)//第二次spfa,去掉新加的点0和相应边
{ for (int i=0;i<=tot;i++)
d[i]=INF;
memset(v,0,sizeof(v));
memset(vv,0,sizeof(vv));
int hea=0,tail=1,now;
d[s]=0; tr[1]=s; v[s]=1; vv[s]++;
while (hea!=tail)
{
hea=(hea+1)%N;
now=tr[hea];
v[now]=0;
for (int k=head[now];k!=-1;k=e[k].next)
if (d[now]+e[k].w<d[e[k].to]&&k<o1)
{d[e[k].to]=d[now]+e[k].w;
if (!v[e[k].to])
{
tail=(tail+1)%N;
tr[tail]=e[k].to;
vv[e[k].to]++;
v[e[k].to]=1;
if (vv[e[k].to]>tot) return 0;
}
}
}
return 1;
}
void doit()
{ int x,y,z;
o=0;memset(head,255,sizeof(head));
for (int i=2;i<=n;i++)add(i,i-1,0);
for (int i=1;i<=m1;i++)
{ scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for (int i=1;i<=m2;i++)
{ scanf("%d%d%d",&x,&y,&z);
add(y,x,-z);
}
o1=o;
for (int i=1;i<=n;i++)
add(0,i,INF/2);//什么数都可以。。0也行,1也行,不过INF不行。。
if (!spfa(0,n+1)) {printf("%d\n",-1);return;}
spfa2(1,n);
if (d[n]==INF||d[1]==INF) printf("%d\n",-2);//为什么上面说INF不行的原因,INF-1都可以
else printf("%d\n",d[n]-d[1]);
}
int main()
{ while (scanf("%d%d%d",&n,&m1,&m2)!=EOF) doit();
return 0;
}
/*
4 1 2
2 4 5
2 3 3
3 4 3
-1
4 2 1
1 3 10
2 4 10
2 4 2
20
第一组数据:要额外设0点
第二组数组:要spfa2
*/