USACO 5.4 Telecowmunication

Telecowmunication

Farmer John's cows like to keep in touch via email so they have created a network of cowputers so that they can intercowmunicate. These machines route email so that if there exists a sequence of c cowputers a1, a2, ..., a(c) such that a1 is connected to a2, a2 is connected to a3, and so on then a1 and a(c) can send email to one another.

Unfortunately, a cow will occasionally step on a cowputer or Farmer John will drive over it, and the machine will stop working. This means that the cowputer can no longer route email, so connections to and from that cowputer are no longer usable.

Two cows are pondering the minimum number of these accidents that can occur before they can no longer use their two favorite cowputers to send email to each other. Write a program to calculate this minimal value for them, and to calculate a set of machines that corresponds to this minimum.

For example the network:

               1
              /  
             3 - 2

shows 3 cowputers connected with 2 lines. We want to send messages between cowputers 1 and 2. Direct lines connect 1-3 and 2-3. If cowputer 3 is down, them there is no way to get a message from 1 to 2.

PROGRAM NAME: telecow

INPUT FORMAT

Line 1Four space-separated integers: N, M, c1, and c2. N is the number of computers (1 <= N <= 100), which are numbered 1..N. M is the number of connections between pairs of cowputers (1 <= M <= 600). The last two numbers, c1 and c2, are the id numbers of the cowputers that the communicating cows are using. Each connection is unique and bidirectional (if c1 is connected to c2, then c2 is connected to c1). There can be at most one wire between any two given cowputers. Computers c1 and c2 will not have a direct connection.
Lines 2..M+1The subsequent M lines contain pairs of cowputers id numbers that have connections between them.

SAMPLE INPUT (file telecow.in)

3 2 1 2
1 3
2 3

OUTPUT FORMAT

Generate two lines of output. The first line is the minimum number of (well-chosen) cowputers that can be down before terminals c1 & c2 are no longer connected. The second line is a minimal-length sorted list of cowputers that will cause c1 & c2 to no longer be connected. Note that neither c1 nor c2 can go down. In case of ties, the program should output the set of computers that, if interpreted as a base N number, is the smallest one.

SAMPLE OUTPUT (file telecow.out)

1
3

 ——————————————————————————————题解

拆点求最小割,每个点相当于一个从u*2-1->u*2的边,为了保证字典序最小,我们把它的权值赋成600*101+u

一条无向边u,v,使u,v两条边首尾相连,u*2->v*2-1,v*2->u*2-1

从原点做floodfill求割

  1 /*
  2 ID: ivorysi
  3 LANG: C++
  4 PROG: telecow
  5 */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <set>
 12 #include <vector>
 13 #include <string.h>
 14 #include <cmath>
 15 #include <stack>
 16 #include <map>
 17 #define siji(i,x,y) for(int i=(x);i<=(y);++i)
 18 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
 19 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
 20 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
 21 #define inf 0x5f5f5f5f
 22 #define ivorysi
 23 #define mo 97797977
 24 #define hash 974711
 25 #define base 47
 26 #define pss pair<string,string>
 27 #define MAXN 5000
 28 #define fi first
 29 #define se second
 30 #define pii pair<int,int>
 31 #define esp 1e-8
 32 typedef long long ll;
 33 using namespace std;
 34 int f[105][105];
 35 struct data {
 36     int to,next,val;
 37 }edge[10005];
 38 int head[205],sumedge=1;
 39 void add(int u,int v,int c) {
 40     edge[++sumedge].to=v;
 41     edge[sumedge].next=head[u];
 42     edge[sumedge].val=c;
 43     head[u]=sumedge;
 44 }
 45 void addtwo(int u,int v,int c) {
 46     add(u,v,c);
 47     add(v,u,0);
 48 }
 49 int n,m,c1,c2,vis[205],mincut;
 50 vector<int> temp,ans,list;
 51 void dfs(int u) {
 52     if(vis[u]==1) return;
 53     vis[u]=1;
 54     for(int i=head[u];i;i=edge[i].next) {
 55         if(edge[i].val!=0) dfs(edge[i].to);
 56     }
 57 }
 58 int dis[205],gap[205];
 59 int sap(int u,int aug) {
 60     if(u==c2*2) return aug;
 61     int flow=0,dmin=2*n-1;
 62     
 63     for(int i=head[u];i;i=edge[i].next) {
 64         int v=edge[i].to;
 65         if(edge[i].val>0) {
 66             if(dis[u]==dis[v]+1) {
 67                 int t=sap(v,min(edge[i].val,aug-flow));
 68                 //应该流走的是aug-flow,为什么每次都是网络流写的出问题qwq
 69                 edge[i].val-=t;
 70                 edge[i^1].val+=t;
 71                 flow+=t;
 72                 if(flow==aug) break;
 73                 if(dis[c1*2-1]>=2*n) return flow;
 74             }
 75             dmin=min(dmin,dis[v]);
 76         }
 77     }
 78     if(!flow){
 79         --gap[dis[u]];
 80         if(gap[dis[u]]==0) dis[c1*2-1]=2*n;
 81         dis[u]=dmin+1;
 82         ++gap[dis[u]]; 
 83     }
 84     return flow;
 85 }
 86 void init() {
 87     scanf("%d%d%d%d",&n,&m,&c1,&c2);
 88     int u,v;
 89     siji(i,1,m) {
 90         scanf("%d%d",&u,&v);
 91         addtwo(u*2,v*2-1,inf+10);addtwo(v*2,u*2-1,inf+10);
 92     }
 93     siji(i,1,n) {
 94         if(i==c1||i==c2) addtwo(i*2-1,i*2,inf+10);
 95         else addtwo(i*2-1,i*2,600*101+i);
 96     }
 97     while(dis[c1*2-1]<2*n) sap(c1*2-1,inf);
 98 }
 99 void solve() {
100     init();
101     dfs(c1*2-1);
102     while(1) {
103         siji(i,1,2*n) {
104             if(vis[i]) {
105                 for(int j=head[i];j;j=edge[j].next) {
106                     if(!vis[edge[j].to]) {
107                         list.push_back(edge[j].to);
108                         if(j%2==0) 
109                             temp.push_back(edge[j^1].val%101);
110                     }
111                 }
112             }
113         }
114         if(temp.size()<1) break; 
115         if(ans.size()<1) {ans=temp;sort(ans.begin(),ans.end());}
116         else {
117             sort(temp.begin(),temp.end());
118             if(ans.size()>temp.size()) ans=temp;
119             else if(ans.size()==temp.size()) {
120                 xiaosiji(i,0,temp.size()) {
121                     if(temp[i]<ans[i]) {ans=temp;break;}
122                 }
123             }
124         }
125         temp.clear();
126         
127         xiaosiji(i,0,list.size()) {
128             dfs(list[i]);
129         }
130         list.clear();
131     }
132     printf("%d\n",ans.size());
133     xiaosiji(i,0,ans.size()) {
134         printf("%d%c",ans[i]," \n"[i==ans.size()-1]);
135     }
136 }
137 int main(int argc, char const *argv[])
138 {
139 #ifdef ivorysi
140     freopen("telecow.in","r",stdin);
141     freopen("telecow.out","w",stdout);
142 #else
143     freopen("f1.in","r",stdin);
144 #endif
145     solve();
146     return 0;
147 }

 

转载于:https://www.cnblogs.com/ivorysi/p/6421645.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值