POJ 2983:Is the Information Reliable?(差分约束)

本文介绍了一种利用差分约束系统和SPFA算法解决特定类型问题的方法。通过建立点之间的关系,并使用SPFA算法检测负权回路来判断输入数据是否存在矛盾。

题目大意:有n个点在一条直线上,有两类关系:P(x,y,v)表示x在y北边v距离处,V(x,y)表示x在y北边至少1距离出,给出一些这样的关系,判断是否有矛盾。

分析:

  差分约束模板题,约束条件P:a-b>=v a-b<=v即a-b>=v b-a<=-v,V:a-b>=1即b-a<=-1,构图spfa判负权回路即可。

  需要注意 的是存图时不能用一个二维数组存边权,因为两点间会有多条边。、

  spfa判断负权回路的方法,记录每个点进队次数,超过点的数目即存在负权回路。

代码:

program infor;
type
  point=^node;
     node=record
          x,len:longint; next:point;
     end;
var
  a:array[0..1000]of point;
  q:array[0..500000]of longint;
  dis,vis:array[0..1000]of longint;
  g:array[0..1000]of boolean;
  n,i,m,x,y,v:longint;  c:char;  p:point;
procedure put(x,y,v:longint);
var p:point;
begin
  new(p);
  p^.x:=x; p^.len:=v; p^.next:=a[y];a[y]:=p;
end;
procedure getnew;
var i:longint;
begin
  fillchar(q,sizeof(q),0);
  fillchar(g,sizeof(g),false); fillchar(vis,sizeof(vis),0);
  for i:=1 to n do dis[i]:=maxlongint div 3;
  for i:=0 to n do begin dispose(a[i]); new(a[i]); a[i]:=nil; end;
  dis[0]:=0; g[0]:=true; q[1]:=0;
end;
function spfa:boolean;
var x,y,h,t:longint; p:point;
begin
  h:=0; t:=1;
  while h<t do
   begin
     inc(h); x:=q[h]; g[x]:=false; new(p);p:=a[x];
     while p<>nil do
      begin
        y:=p^.x;
        if dis[x]+p^.len<dis[y] then
          begin
            dis[y]:=dis[x]+p^.len;
            if g[y]=false then
              begin
                inc(t); q[t]:=y; g[y]:=true;
              end;
            inc(vis[y]); if vis[y]>n then exit(false);
          end;
        p:=p^.next;
      end;
    end;
  exit(true);
end;
begin
  readln(n,m);
  while (n<>0)or(m<>0) do
   begin
     getnew;
     for i:=1 to n do put(i,0,0);
     for i:=1 to m do
      begin
        read(c);
        if c='P' then
         begin read(x,y,v); put(x,y,v); put(y,x,-v); end
        else if c='V' then  begin read(x,y); put(y,x,-1); end;
        if i<m then readln;
      end;
     if spfa then writeln('Reliable') else writeln('Unreliable');
     n:=0; m:=0;
     readln(n,m);
   end;
end.
View Code

 

转载于:https://www.cnblogs.com/qtyytq/p/5637916.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值