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

本文探讨了差分约束系统在解决牛间距问题中的应用,详细介绍了如何通过差分约束系统来处理牛之间的距离限制,并提供了一个具体的算法实现步骤及代码解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

转载于:https://www.cnblogs.com/Thispoet/archive/2011/09/11/2173631.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值