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

 

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值