POJ 1364:King(差分约束)

题目大意:判断是否存在一个长度为n的序列满足给出的不等关系。

分析:

  将序列和转化成用两个前缀和之差来表示即可变为差分约束系统。

  需要注意的是不能忘记n要加+1,因为还有一个特殊源点,自己因为n:=n+1的位置放在数组预处理的后面所以出错了。

代码:

  

program king;
type
  point=^node;
     node=record
          x,len:longint; next:point;
     end;
var
  a:array[0..201]of point;
  q:array[0..50000]of longint;
  dis,vis:array[0..201]of longint;
  g:array[0..201]of boolean;
  n,i,m,x,y,v,t,l:longint;  c1,c2:char; s1:string; 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:=0 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[n]:=0; g[n]:=true; q[1]:=n;
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
  read(n);
  while n>0 do
  begin
    inc(n); getnew;
    read(m);  readln;
    for i:=0 to n-1 do put(i,n,0);
    for i:=1 to m do
    begin
     readln(s1);
     t:=pos('t',s1); l:=pos(' ',s1);
     val(copy(s1,1,l-1),x); val(copy(s1,l+1,t-3-l),y);val(copy(s1,t+2,length(s1)-t-1),v);
     if s1[t-1]='l' then put(x+y,x-1,v-1);
     if s1[t-1]='g' then put(x-1,x+y,-v-1);
    end;
    if spfa then writeln('lamentable kingdom') else writeln('successful conspiracy');
    read(n);
  end;
end.
View Code

 

posted @ 2016-07-03 22:20  QTY_YTQ  阅读(173)  评论(0)    收藏  举报