[Poj]2983——差分约束系统

[题目大意]
  • 给定N个点的关系,关系有两种,一是A在B的北面恰好X光年,第二种是A在B的北面,没有具体的距离.问能不能找到一种安排是所有的关系成立

[分析题解]
  •  非常明显的差分约束系统
  • P A B X    ->       A-B=X      ->    A-B<=X and A-B>=X   ->  A-B<=X and B-A<=-X

    V A B     ->       A-B>=1    ->    B-A<=-1

  • 这样就转换为一个标准的差分约束系统,然后建图,加超级点,求最短路判负权环即可。

[个人代码]
Bellman_ford
 1 //10105183      perseawe        2983    Accepted        3236K   344MS   Pascal  1668B   2012-04-22 10:04:42
 2 
 3 Const
 4   MaxNode=1000+1000+100;
 5   MaxEdge=100000+100000+1000;
 6 
 7 Var
 8   ans:Boolean;
 9   tot,n,m,Src:Longint;
10   Dis:Array [0..MaxNode] of Longint;
11   Edge:Array [0..MaxEdge] of Record u,v,c:Longint;end;
12 
13 Procedure AddEdge(u,v,c:Longint);
14   begin
15     inc(tot);
16     Edge[tot].u:=u;Edge[tot].v:=v;Edge[tot].c:=c;
17   end;
18 
19 Procedure Init;
20   var
21     i,u,v,c:longint;
22     ch:char;
23   begin
24     readln(n,m);
25     tot:=0;
26     for i:=1 to m do
27       begin
28         read(ch);
29         if ch='P' then
30           begin
31             readln(u,v,c);
32             AddEdge(v,u,c);
33             AddEdge(u,v,-c);
34           end
35         else
36           begin
37             readln(u,v);
38             AddEdge(u,v,-1);
39           end;
40       end;
41   end;
42 
43 Function Bellman_Ford:Boolean;
44   var
45     Flag:Boolean;
46     I,J:Longint;
47   begin
48     For I:=1 to N do
49       Begin
50         Flag:=False;
51         For J:=1 to tot do
52           if Dis[Edge[J].v]>Dis[Edge[J].u]+Edge[J].c then
53             begin
54               Dis[Edge[J].v]:=Dis[Edge[J].u]+Edge[J].c;
55               Flag:=True;
56             end;
57         if Not(Flag) then Break;
58       End;
59     For J:=1 to tot do
60       if Dis[Edge[J].v]>Dis[Edge[J].u]+Edge[J].c then
61         Exit(False);
62     Exit(True);
63   end;
64 
65 Procedure Main;
66   begin
67     ans:=Bellman_Ford;
68   end;
69 
70 Procedure Print;
71   begin
72     if ans then writeln('Reliable'else writeln('Unreliable');
73   end;
74 
75 Begin
76   //Assign(INPUT,'P2983.in');Reset(INPUT);
77   //Assign(OUTPUT,'P2983.out');Rewrite(OUTPUT);
78   While not(seekeof) do
79     begin
80       Init;
81       Main;
82       Print;
83     end;
84   //Close(INPUT);
85   //Close(OUTPUT);
86 End.
Spfa
  1 //10105210      perseawe        2983    Accepted        3272K   313MS   Pascal  2607B   2012-04-22 10:10:31
  2 
  3 Const
  4   MaxNode=1000+1000+100;
  5   MaxEdge=100000+100000+1000;
  6 
  7 Var
  8   ans:Boolean;
  9   n,m,tot,Src:Longint;
 10   Edge:Array [0..MaxEdge] of Record c,wh,next:Longint;end;
 11   hv,dis,Num:array [0..MaxNode] of Longint;
 12   Line:Array [0..MaxNode] of Longint;
 13   Use:Array [0..MaxNode] of Boolean;
 14 
 15 Procedure AddEdge(u,v,c:Longint);
 16   begin
 17     inc(tot);
 18     Edge[tot].next:=hv[u];hv[u]:=tot;
 19     Edge[tot].wh:=v;Edge[tot].c:=c;
 20   end;
 21 
 22 Procedure Init;
 23   var
 24     i,u,v,c:longint;
 25     ch:char;
 26   begin
 27     readln(n,m);
 28     tot:=0;
 29     Fillchar(hv,sizeof(hv),0);
 30     for i:=1 to m do
 31       begin
 32         read(ch);
 33         if ch='P' then
 34           begin
 35             readln(u,v,c);
 36             AddEdge(v,u,c);
 37             AddEdge(u,v,-c);
 38           end
 39         else
 40           begin
 41             readln(u,v);
 42             AddEdge(u,v,-1);
 43           end;
 44       end;
 45     Src:=n+1;
 46     for i:=1 to n do AddEdge(Src,i,0);
 47   end;
 48 
 49 Function Spfa:Boolean;
 50   var
 51     I,top,tail,u,v,tnode:Longint;
 52   begin
 53     For I:=1 to n do Dis[I]:=1000000000;Dis[Src]:=0;
 54     Fillchar(Use,sizeof(Use),False);Use[Src]:=True;
 55     Fillchar(Num,sizeof(Num),0);Num[Src]:=1;
 56     top:=0;tail:=1;line[1]:=Src;
 57     Repeat
 58       inc(top);
 59       if top>MaxNode then top:=1;
 60       u:=line[top];
 61       Use[u]:=False;
 62       tnode:=hv[u];
 63       while tnode<>0 do
 64         begin
 65           v:=Edge[tnode].wh;
 66           if Dis[v]>Dis[u]+Edge[tnode].c then
 67             begin
 68               Dis[v]:=Dis[u]+Edge[tnode].c;
 69               if not(use[v]) then
 70                 begin
 71                   use[v]:=True;
 72                   inc(tail);
 73                   if tail>MaxNode then tail:=1;
 74                   Line[tail]:=v;
 75                   Inc(Num[v]);
 76                   if Num[v]>N then Exit(False);
 77                 end;
 78             end;
 79           tnode:=Edge[tnode].next;
 80         end;
 81     Until top=tail;
 82     For i:=1 to n do
 83       begin
 84         u:=i;
 85         tnode:=hv[u];
 86         while tnode<>0 do
 87           begin
 88             v:=Edge[tnode].wh;
 89             if Dis[v]>Dis[u]+Edge[tnode].c then exit(False);
 90             tnode:=Edge[tnode].next;
 91           end;
 92       end;
 93     Exit(true);
 94   end;
 95 
 96 Procedure Main;
 97   begin
 98     ans:=Spfa;
 99   end;
100 
101 Procedure Print;
102   begin
103     if ans then writeln('Reliable'else writeln('Unreliable');
104   end;
105 
106 Begin
107   //assign(input,'P2983.in');Reset(INPUT);
108   //assign(output,'P2983.out');Rewrite(OUTPUT);
109   while not(seekeof) do
110     begin
111       Init;
112       Main;
113       Print;
114     end;
115   //close(Input);
116   //close(OUTPUT);
117 End.
Spfa
  1 //10105210      perseawe        2983    Accepted        3272K   313MS   Pascal  2607B   2012-04-22 10:10:31
  2 
  3 Const
  4   MaxNode=1000+1000+100;
  5   MaxEdge=100000+100000+1000;
  6 
  7 Var
  8   ans:Boolean;
  9   n,m,tot,Src:Longint;
 10   Edge:Array [0..MaxEdge] of Record c,wh,next:Longint;end;
 11   hv,dis,Num:array [0..MaxNode] of Longint;
 12   Line:Array [0..MaxNode] of Longint;
 13   Use:Array [0..MaxNode] of Boolean;
 14 
 15 Procedure AddEdge(u,v,c:Longint);
 16   begin
 17     inc(tot);
 18     Edge[tot].next:=hv[u];hv[u]:=tot;
 19     Edge[tot].wh:=v;Edge[tot].c:=c;
 20   end;
 21 
 22 Procedure Init;
 23   var
 24     i,u,v,c:longint;
 25     ch:char;
 26   begin
 27     readln(n,m);
 28     tot:=0;
 29     Fillchar(hv,sizeof(hv),0);
 30     for i:=1 to m do
 31       begin
 32         read(ch);
 33         if ch='P' then
 34           begin
 35             readln(u,v,c);
 36             AddEdge(v,u,c);
 37             AddEdge(u,v,-c);
 38           end
 39         else
 40           begin
 41             readln(u,v);
 42             AddEdge(u,v,-1);
 43           end;
 44       end;
 45     Src:=n+1;
 46     for i:=1 to n do AddEdge(Src,i,0);
 47   end;
 48 
 49 Function Spfa:Boolean;
 50   var
 51     I,top,tail,u,v,tnode:Longint;
 52   begin
 53     For I:=1 to n do Dis[I]:=1000000000;Dis[Src]:=0;
 54     Fillchar(Use,sizeof(Use),False);Use[Src]:=True;
 55     Fillchar(Num,sizeof(Num),0);Num[Src]:=1;
 56     top:=0;tail:=1;line[1]:=Src;
 57     Repeat
 58       inc(top);
 59       if top>MaxNode then top:=1;
 60       u:=line[top];
 61       Use[u]:=False;
 62       tnode:=hv[u];
 63       while tnode<>0 do
 64         begin
 65           v:=Edge[tnode].wh;
 66           if Dis[v]>Dis[u]+Edge[tnode].c then
 67             begin
 68               Dis[v]:=Dis[u]+Edge[tnode].c;
 69               if not(use[v]) then
 70                 begin
 71                   use[v]:=True;
 72                   inc(tail);
 73                   if tail>MaxNode then tail:=1;
 74                   Line[tail]:=v;
 75                   Inc(Num[v]);
 76                   if Num[v]>N then Exit(False);
 77                 end;
 78             end;
 79           tnode:=Edge[tnode].next;
 80         end;
 81     Until top=tail;
 82     For i:=1 to n do
 83       begin
 84         u:=i;
 85         tnode:=hv[u];
 86         while tnode<>0 do
 87           begin
 88             v:=Edge[tnode].wh;
 89             if Dis[v]>Dis[u]+Edge[tnode].c then exit(False);
 90             tnode:=Edge[tnode].next;
 91           end;
 92       end;
 93     Exit(true);
 94   end;
 95 
 96 Procedure Main;
 97   begin
 98     ans:=Spfa;
 99   end;
100 
101 Procedure Print;
102   begin
103     if ans then writeln('Reliable'else writeln('Unreliable');
104   end;
105 
106 Begin
107   //assign(input,'P2983.in');Reset(INPUT);
108   //assign(output,'P2983.out');Rewrite(OUTPUT);
109   while not(seekeof) do
110     begin
111       Init;
112       Main;
113       Print;
114     end;
115   //close(Input);
116   //close(OUTPUT);
117 End.

[启发总结]
  1.  用seekeof而不是eof,以后要改习惯了,在这道题上被坑的好惨
  2. 原来的spfa模板没有办法处理自环,这次对其进行了修正.
posted @ 2012-04-22 10:36  PerSeAwe  阅读(296)  评论(0编辑  收藏  举报