POJ3169 Layout——差分约束系统+SPFA——Pku3169

本题是一道典型的差分约束系统问题。关于差分约束系统,请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.



你可能感兴趣的:(layout)