P1345 [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


思路
  肯定是最小割,直接交不要怂
  观察一下,这是蓝题,不会有这样的送分题的。
  再观察一下,发现踩烂的是电脑。
  所以就变成了求最小割点。不是tarjan
  最小割点的求法: 把每个点拆成流入流出两个点, 中间连一条费用为 1 的边,这条边被破坏即这个点被破坏。
  点与点之间理所应当连inf的容量,保证不会把连线给拆了。
CODE

  
  1 #include <bits/stdc++.h>
  2 #define dbg(x) cout << #x << "=" << x << endl
  3 #define eps 1e-8
  4 #define pi acos(-1.0)
  5 
  6 using namespace std;
  7 typedef long long LL;
  8 
  9 template<class T>inline void read(T &res)
 10 {
 11     char c;T flag=1;
 12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
 13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
 14 }
 15 
 16 namespace _buff {
 17     const size_t BUFF = 1 << 19;
 18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
 19     char getc() {
 20         if (ib == ie) {
 21             ib = ibuf;
 22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
 23         }
 24         return ib == ie ? -1 : *ib++;
 25     }
 26 }
 27 
 28 int qread() {
 29     using namespace _buff;
 30     int ret = 0;
 31     bool pos = true;
 32     char c = getc();
 33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
 34         assert(~c);
 35     }
 36     if (c == '-') {
 37         pos = false;
 38         c = getc();
 39     }
 40     for (; c >= '0' && c <= '9'; c = getc()) {
 41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
 42     }
 43     return pos ? ret : -ret;
 44 }
 45 
 46 const int maxn = 1e4 + 7;
 47 const int inf = 0x3f3f3f3f;
 48 
 49 int n,m,cnt = 1,s,t;
 50 
 51 int maxflow;
 52 int head[maxn];
 53 
 54 struct Node {
 55     int v,dis,nxt;
 56 }edge[maxn << 2];
 57 
 58 void BuildGraph(int u,int v,int dis){
 59     edge[++cnt].nxt = head[u];
 60     edge[cnt].v = v;
 61     edge[cnt].dis = dis;
 62     head[u] = cnt;
 63 
 64     edge[++cnt].nxt = head[v];
 65     edge[cnt].v = u;
 66     edge[cnt].dis = 0;
 67     head[v] = cnt;
 68 }
 69 
 70 int depth[maxn];
 71 
 72 bool bfs() {
 73     queue<int> q;
 74     while(!q.empty())
 75         q.pop();
 76     memset(depth,0,sizeof(depth));
 77     depth[s] = 1;
 78     q.push(s);
 79     while(!q.empty()){
 80         int u = q.front();
 81         q.pop();
 82         for(int i = head[u]; i; i = edge[i].nxt){
 83             int v = edge[i].v;
 84             if(edge[i].dis && !depth[v]){
 85                 depth[v] = depth[u] + 1;
 86                 if(v == t)
 87                     return true;
 88                 q.push(v);
 89             }
 90         }
 91     }
 92     return false;
 93 }
 94 
 95 int Dinic(int u,int flow) {//最大流
 96     if(u == t)
 97         return flow;
 98     int rest = flow,temp;//残量网络
 99     for(int i = head[u];i;i = edge[i].nxt) {
100         int v = edge[i].v;
101         if(depth[v] == depth[u] + 1 && edge[i].dis){
102             temp = Dinic(v,min(rest,edge[i].dis));
103             if(!temp)depth[v] = 0;
104             rest -= temp;
105             edge[i].dis -= temp;
106             edge[i ^ 1].dis += temp;
107         }
108     }
109     return flow - rest;
110 }
111 
112 int main(){
113     scanf("%d %d %d %d",&n, &m, &s, &t);
114     for(int i = 1;i <= n;i++){
115         BuildGraph(i, i + n, 1);
116     }
117 
118     int u,v;
119     for(int i = 1; i <= m; i++){
120         scanf("%d %d",&u, &v);
121         BuildGraph(u + n,v,inf);
122         BuildGraph(v + n,u,inf);
123     }
124     s += n;
125     int flow = 0;
126     while(bfs()){
127         while(flow = Dinic(s,inf))
128             maxflow += flow;
129     }
130     printf("%d\n",maxflow);
131     return 0;
132 }
View Code

猜你喜欢

转载自www.cnblogs.com/orangeko/p/12359769.html