[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

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

[个人代码]
ExpandedBlockStart.gif 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.
ExpandedBlockStart.gif 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.
ExpandedBlockStart.gif 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模板没有办法处理自环,这次对其进行了修正.

转载于:https://www.cnblogs.com/perseawe/archive/2012/04/22/Poj2983.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值