源代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct Node
{
int S,To,Next;
}Edge[20001];
deque <int> Q;
int n,m1,m2,Num,i[1001],Sum[1001],Head[1001];
bool In[1001]={0};
void Add(int t1,int t2,int t) //边表。
{
Edge[++Num].S=t;
Edge[Num].To=t2;
Edge[Num].Next=Head[t1];
Head[t1]=Num;
}
bool SPFA() //SPFA+SLF。
{
i[1]=0;
In[1]=true;
Q.push_back(1);
while (!Q.empty())
{
int t=Q.front();
In[t]=false;
Q.pop_front();
for (int a=Head[t];a;a=Edge[a].Next)
{
int T=Edge[a].To;
if (i[T]>i[t]+Edge[a].S)
{
Sum[T]=Sum[t]+1;
if (Sum[T]>n)
return true;
i[T]=i[t]+Edge[a].S;
if (!In[T])
{
In[T]=true;
if (!Q.empty()&&i[T]>i[Q.front()])
Q.push_front(T);
else
Q.push_back(T);
}
}
}
}
return false;
}
void Solve() //差分约束系统。
{
Num=0;
memset(i,0x3f,sizeof(i));
memset(Sum,0,sizeof(Sum));
memset(Head,0,sizeof(Head)); //注意初始化。
for (int a=0;a<m1;a++)
{
int t,t1,t2;
scanf("%d%d%d",&t1,&t2,&t);
Add(min(t1,t2),max(t1,t2),t); //编号性质。
}
for (int a=0;a<m2;a++)
{
int t,t1,t2;
scanf("%d%d%d",&t1,&t2,&t);
Add(max(t1,t2),min(t1,t2),-t); //变号。
}
if (SPFA()) //存在负环
printf("-1\n");
else
if (i[n]==i[0])
printf("-2\n");
else
printf("%d\n",i[n]);
}
int main()
{
while (scanf("%d%d%d",&n,&m1,&m2)==3) //坑人的多组数据!
Solve();
return 0;
}
/*
因为是队列,所以编号是单调递增的,只需要区分符号,再SPFA即可。
*/