本题是一道典型的差分约束系统问题。关于差分约束系统,请visit 百度百科:http://baike.baidu.com/view/1008149.htm

简略成一句话,那就是:对于i-j<=k 这样一个条件,就在j和i之间连一条有向边,边权为k

对于本题,有两种条件,两头牛的距离不大于或者不小于k,距离不大于k的时候按照差分约束系统的条件即可进行,而距离不小于k时则可以按照如下数学方法转换:

原条件为:i-j>=k 可转化为 j-i<=-k,即在i与j之间连一条边权为-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.