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 1 Four 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+1 The 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 }
时间: 2024-08-26 15:15:15

USACO 5.4 Telecowmunication的相关文章

USACO Section 5.4 TeleCowmunication(最小割)

挺裸的一道最小割.把每台电脑拆成一条容量为1的边,然后就跑最大流.从小到大枚举每台电脑,假如去掉后 最大流=之前最大流+1,那这台电脑就是answer之一了. -------------------------------------------------------------------------------------- #include<cstdio> #include<vector> #include<cstring> #define rep(i,r) f

usaco Telecowmunication

读完题就知道是求两点独立轨条数的问题. 就是将一个点拆成两个点求最大流. 但是在如何将一个点拆分成两个点之后如何建图的问题上纠结了好久. 其实就是将一个点拆分成流入点和流出点.然后流入到流出之间有一条容量为1的有向弧. 原来的a和b之间联通的话,就是a的出点流到了b的入点,且b的出点流到了a的入点. 还有一个问题要解决,就是有多个最小割时如何得到集合大小最小,且字典序最小的集合. 其实因为拆分之后的流入点到流出点之间的容量为1,且原来每个点拆分之后的自己的流入和流出之间的容量都为1. 可以证明所

【USACO 5.4.3】TeleCowmunication

题目大意 给一幅由N个点和M条无向边组成的图,要求删掉最少的点使得c1和c2无法连通(不能删这两个点).输出删的点数以及要删的点,要求删的点的字典序最小. 题解 我记得以前貌似是删边的.删点其实也类似,把点转换成边就可以了.所以就要拆点了,拆点的方法不多说. 然后跑一遍最小割(最大流),原来的边的流量设为无限大,拆点的边就置为1,不过要注意的是这里是无向边. 主要问题就是怎么让答案的字典序最小.其实枚举就行了!枚举每一个点,然后删点,跑最大流,看一下流量是否变小,变小了就真(是真的!)删掉这个点

USACO 5.4 章节

Canada Tour 题目大意 双向连通图,点从左向右排列, 你需要先从最左的点到最右的点,(过程中只能从左向右走) 然后再从最右的点返回最左的点,(过程中只能从右向左走) 过程中除了最左的点,其它点都至多能经过一次 求最多能经过的点的个数 题解 从右向左走反过来,就是说从左向右走,题目变成从最左两条不相交到达最右的路径,经过最多的点 一个问题是如何解决没有重复的点 这里的解决方案是 dp[i][j]表示没有重复的点的情况下 一条路径走到点i,一条路径走到点j,经过的点的最大的个数 在状态转移

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

USACO prefix TrieTree + DP

/* ID:kevin_s1 PROG:prefix LANG:C++ */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <map> #include <set> #include <algorithm> #include <cstdlib>

【USACO 1.3.4】牛式

[題目描述 ] 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. * * * x * * ---------- * * * * * * ---------- * * * * 数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0. 注意一下在美国的学校中教的"部分乘积",第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积. 写一个程序找出所有的牛式. [格式] INPUT FORMAT: (f

AC日记——[USACO5.4]奶牛的电信Telecowmunication 洛谷 P1345

[USACO5.4]奶牛的电信Telecowmunication 思路: 水题: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 205 #define maxm 20005 #define INF 0x3f3f3f3f int head[maxn],cnt=1,n,m,E[m

USACO Chapter 1 Section 1.1

USACO的题解和翻译已经很多了... 我只是把自己刷的代码保存一下. 1.PROB Your Ride Is Here 1 /* 2 ID:xiekeyi1 3 PROG:ride 4 LANG:C++ 5 */ 6 7 #include<bits/stdc++.h> 8 using namespace std ; 9 10 int main() 11 { 12 freopen("ride.in","r",stdin); 13 freopen(&quo