本题是一道典型的差分约束系统问题。关于差分约束系统,请visit 百度百科:http://baike.baidu.com/view/1008149.htm
简略成一句话,那就是:对于i-j<=k 这样一个条件,就在i和j之间连一条有向边,边权为k
对于本题,有两种条件,两头牛的距离不大于或者不小于k,距离不大于k的时候按照差分约束系统的条件即可进行,而距离不小于k时则可以按照如下数学方法转换:
原条件为:i-j>=k 可转化为 j-i<=-k,即在j与i之间连一条边权为-k的有向边。
之后一般的SPFA即可。如果存在负环,就说明不存在解,如果起点到终点没有路径,那么说明距离可以到达无穷大
SPFA判断负环的方法:如果一个共n个点的图中,有一点入队次数大于n-1,说明图中存在负环。
CODE
Program Layout;//By_thispoet
Const
maxn=1000;
Var
i,j,k,ml,md,s,n,a,b,p,sum :Longint;
pre,other,last,len,times :Array[1..maxn*500]of Longint;
h,t :Longint;
seq :Array[1..maxn*500]of Longint;
dist :Array[1..maxn]of Longint;
Procedure Swap(var i,j:Longint);
begin
i:=i xor j;
j:=i xor j;
i:=i xor j;
end;
BEGIN
readln(n,ml,md);
for i:=1 to ml do
begin
readln(a,b,p);
if a>b then Swap(a,b);
inc(sum);pre[sum]:=last[a];last[a]:=sum;other[sum]:=b;len[sum]:=p;
end;
for i:=1 to md do
begin
readln(a,b,p);
if a<b then Swap(a,b);
inc(sum);pre[sum]:=last[a];last[a]:=sum;other[sum]:=b;len[sum]:=-p;
end;
{------------------init---------------------}
h:=0;t:=1;seq[1]:=1;
fillchar(dist,sizeof(dist),127);
fillchar(times,sizeof(times),0);
dist[1]:=0;
while h<t do
begin
inc(h);
i:=seq[h];
j:=last[i];
while j<>0 do
begin
k:=other[j];
if dist[k]>dist[i]+len[j] then
begin
dist[k]:=dist[i]+len[j];
inc(t);seq[t]:=k;
inc(times[k]);
if times[k]>n then
begin
writeln(-1);
halt;
end;
end;
j:=pre[j];
end;
end;
{-------------------SPFA--------------------}
if dist[n]>(maxlongint>>1) then
writeln(-2) else writeln(dist[n]);
{----------------output it-------------------}
END.