洛谷P13445 [USACO5.4]奶牛的电信Telecowmunication(网络流)

题目描述

农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相连,a2与a3相连,等等,那么电脑a1和a(c)就可以互发电邮。

很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。

有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。

以如下网络为例:

1*

/

3 - 2*

这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。

输入输出格式

输入格式:

第一行 四个由空格分隔的整数:N,M,c1,c2.N是电脑总数(1<=N<=100),电脑由1到N编号。M是电脑之间连接的总数(1<=M<=600)。最后的两个整数c1和c2是上述两头奶牛使用的电脑编号。连接没有重复且均为双向的(即如果c1与c2相连,那么c2与c1也相连)。两台电脑之间至多有一条连接。电脑c1和c2不会直接相连。

第2到M+1行 接下来的M行中,每行包含两台直接相连的电脑的编号。

 

输出格式:

一个整数表示使电脑c1和c2不能互相通信需要坏掉的电脑数目的最小值。

 

输入输出样例

输入样例#1:
3 2 1 2
1 3
2 3
输出样例#1:
1


题解:
把一个点拆成两个点,连上容量为1的边,然后把其他边连一连求一下最小割就好了。
刚开始求c1的入点到c2的出点的最小割了,WA了一发,其实是求c1的出点到c2的汇点的最小割。要注意。
 1 program rrr(input,output);
 2 const
 3   inf=123456789;
 4 type
 5   etype=record
 6      t,c,next,rev:longint;
 7   end;
 8 var
 9    e:array[0..5000]of etype;
10    a,d,cur:array[-660..660]of longint;
11    q:array[0..1222]of longint;
12    n,m,c1,c2,i,x,y,cnt,ans,h,t:longint;
13 function min(a,b:longint):longint;
14 begin
15    if a<b then exit(a) else exit(b);
16 end;
17 procedure ins(x,y,c:longint);
18 begin
19    inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].next:=a[x];a[x]:=cnt;
20 end;
21 procedure add(x,y,c:longint);
22 begin
23    ins(x,y,c);e[cnt].rev:=cnt+1;ins(y,x,0);e[cnt].rev:=cnt-1;
24 end;
25 procedure bfs;
26 begin
27    for i:=-n to n do d[i]:=-1;
28    h:=0;t:=1;q[1]:=c1;d[c1]:=0;
29    while h<t do
30       begin
31          inc(h);i:=a[q[h]];
32          while i<>0 do
33             begin
34                if (d[e[i].t]=-1) and (e[i].c>0) then
35                   begin
36                      d[e[i].t]:=d[q[h]]+1;
37                      inc(t);q[t]:=e[i].t;
38                   end;
39                i:=e[i].next;
40             end;
41       end;
42 end;
43 function dfs(k,f:longint):longint;
44 var
45   ans,i,r:longint;
46 begin
47    if (k=-c2) or (f=0) then exit(f);
48    ans:=0;i:=cur[k];
49    while i<>0 do
50       begin
51          if (d[e[i].t]=d[k]+1) and (e[i].c>0) then
52             begin
53                r:=dfs(e[i].t,min(f,e[i].c));
54                dec(e[i].c,r);inc(e[e[i].rev].c,r);
55                dec(f,r);inc(ans,r);
56                if f=0 then break;
57             end;
58          i:=e[i].next;cur[k]:=i;
59       end;
60    if f>0 then d[k]:=-1;
61    exit(ans);
62 end;
63 begin
64    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
65    readln(n,m,c1,c2);
66    fillchar(a,sizeof(a),0);cnt:=0;
67    for i:=1 to n do add(-i,i,1);
68    for i:=1 to m do begin read(x,y);add(x,-y,inf);add(y,-x,inf); end;
69    ans:=0;
70    while true do
71       begin
72          bfs;
73          if d[-c2]=-1 then break;
74          for i:=-n to n do cur[i]:=a[i];
75          ans:=ans+dfs(c1,inf);
76       end;
77    write(ans);
78    close(input);close(output);
79 end.

 

 
posted @ 2017-04-11 20:14  Klaier  阅读(242)  评论(0编辑  收藏  举报