挺裸的一道最小割。把每台电脑拆成一条容量为1的边,然后就跑最大流。从小到大枚举每台电脑,假如去掉后 最大流=之前最大流+1,那这台电脑就是answer之一了。

--------------------------------------------------------------------------------------

#include<cstdio>
#include<vector>
#include<cstring>
#define rep(i,r) for(int i=0;i<r;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define Rep(i,l,r) for(int i=l;i<r;i++)
using namespace std;
const int maxn=100*2+5;
const int inf=1<<30;
int x[maxn][2];
struct Edge {
int from,to,cap,flow;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f) {}
};
struct ISAP {
int n,m,s,t;
int p[maxn];
int cur[maxn];
int num[maxn];
int d[maxn];
vector<int> g[maxn];
vector<Edge> edges;
void init(int n) {
this->n=n;
rep(i,n) g[i].clear();
edges.clear();
}
int addEdge(int from,int to,int cap) {
edges.push_back( (Edge) {from,to,cap,0} );
edges.push_back( (Edge) {to,from,0,0} );
m=edges.size();
g[from].push_back(m-2);
g[to].push_back(m-1);
return m-2;
}
int augment() {
int x=t,a=inf;
while(x!=s) {
Edge &e=edges[p[x]];
a=min(a,e.cap-e.flow);
x=edges[p[x]].from;
}
x=t;
while(x!=s) {
edges[p[x]].flow+=a;
edges[p[x]^1].flow-=a;
x=edges[p[x]].from;
}
return a;
}
int maxFlow(int s,int t) {
int flow=0;
this->s=s; this->t=t;
clr(d,0); clr(num,0); clr(cur,0); clr(p,0);
rep(i,edges.size()) edges[i].flow=0;
rep(i,n) num[d[i]]++;
int x=s;
while(d[s]<n) {
if(x==t) { flow+=augment(); x=s; }
int ok=0;
Rep(i,cur[x],g[x].size()) {
Edge &e=edges[g[x][i]];
if(e.cap>e.flow && d[x]==d[e.to]+1) {
ok=1;
p[e.to]=g[x][i];
cur[x]=i;
x=e.to;
break;
}
}
if(!ok) {
int m=n-1;
rep(i,g[x].size()) {
Edge &e=edges[g[x][i]];
if(e.cap>e.flow) m=min(m,d[e.to]);
}
if(--num[d[x]]==0) break;
num[d[x]=m+1]++;
cur[x]=0;
if(x!=s) x=edges[p[x]].from;
}
}
return flow;
}
} isap;
int main()
{
freopen("telecow.in","r",stdin);
freopen("telecow.out","w",stdout);
clr(x,-1);
int n,m,s,t,a,b;
scanf("%d%d%d%d",&n,&m,&s,&t);
--s; --t;
isap.init(2*n);
rep(i,n) {
   x[i][0]=isap.addEdge(i,i+n,1);
   x[i][1]=isap.addEdge(i+n,i,1);
}
rep(i,m) {
scanf("%d%d",&a,&b);
--a; --b;
isap.addEdge(a+n,b,m+1);
isap.addEdge(b+n,a,m+1);
}
int maxFlow=isap.maxFlow(s+n,t);
vector<int> ans; ans.clear();
rep(i,n) if(i!=s && i!=t) {
isap.edges[x[i][0]].cap=0;
isap.edges[x[i][1]].cap=0;
   if(isap.maxFlow(s+n,t)==maxFlow-1) {
ans.push_back(i+1);
maxFlow--;
} else {
   isap.edges[x[i][0]].cap=1;
   isap.edges[x[i][1]].cap=1;
}
if(!maxFlow) break;
}
printf("%d\n",ans.size());
printf("%d",ans[0]);
Rep(i,1,ans.size()) printf(" %d",ans[i]);
printf("\n");
return 0;
}

--------------------------------------------------------------------------------------

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 1 with 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 questioning 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. Computer c1 and c2 will not have a direction 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 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

USACO Section 5.4 TeleCowmunication(最小割)的更多相关文章

  1. LG1345 「USACO5.4」Telecowmunication 最小割

    问题描述 LG1345 题解 点边转化,最小割,完事. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; tem ...

  2. [USACO5.4]奶牛的电信Telecowmunication 最小割

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

  3. [Luogu P1345] [USACO5.4]奶牛的电信Telecowmunication (最小割)

    题面 传送门:https://www.luogu.org/problemnew/show/P1345 ] Solution 这道题,需要一个小技巧了解决. 我相信很多像我这样接蒟蒻,看到这道题,不禁兴 ...

  4. [USACO Section 4.4]追查坏牛奶Pollutant Control (最小割)

    题目链接 Solution 一眼看过去就是最小割,但是要求割边最少的最小的割. 所以要用骚操作... 建边的时候每条边权 \(w = w * (E+1) + 1;\) 那么这样建图跑出来的 \(max ...

  5. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  6. USACO 4.4.2 追查坏牛奶 oj1341 网络流最小割问题

    描述 Description 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网.这个送货网很大,而且关 ...

  7. USACO 4.4 Pollutant Control (网络流求最小割割集)

    Pollutant ControlHal Burch It's your first day in Quality Control at Merry Milk Makers, and already ...

  8. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication(最小割)

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

  9. P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】【最大流】

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

随机推荐

  1. 浙大PAT 7-06 题解

    #include <stdio.h> #include <iostream> #include <algorithm> #include <math.h> ...

  2. java读取TXT文件的方法

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...

  3. C# OR/Mapping 数据处理模式学习

    为什么要提出O/R Mapping概念 程序语言已经由面向过程的模型全面转向为面向对象的模型,UML的出现更加革新了软件开发方法论.然而数据库模型却从未随着开发语言的进步而随之革新,仍然使用面向关系的 ...

  4. cmd命令行--切换盘符

  5. English - when用法

    一.作为副词,它有以下的用法:  1. 作为疑问副词,引导特殊疑问句,意为“什么时候:何时”.如: ( 1 ) When will they come back?( 2 ) What time wil ...

  6. sql 练习(3)

    1.打印九九乘法表 ) ,exp)) A, ,exp))B, ,exp))C, ,exp))D, ,exp))E, ,exp))F, ,exp))G, ,exp))H, ,exp))I from ( ...

  7. TOJ 1139.Compromise

    2015-06-03 问题简述: 大概就是输入两段文本(用小写英文字母表示),分别用#表示一段话的结束输入,输出这两个文本的最长公共子序列. 简单的LCS问题,但是输入的是一段话了,而且公共部分比较是 ...

  8. Android 一个抽奖应用的逆向破解全流程之加固自己应用

    转自: <a href="http://www.pedant.cn/2014/07/22/crack-a-draw-app/">http://www.pedant.cn ...

  9. printf与scanf的返回值、注意点

    printf()的返回值为其输出字符串常量的字符数(注意字符数与字数的区别)注意计数针对所有的打印字符,包括空格和不可见的换行字符(不包括字符串的空字符). scanf()函数返回成功读入的项目的个数 ...

  10. android方向键被锁定的问题

    当虚拟机启动的时候,很多情况是旁边的方向键不能点击,处于一种被锁定的状态,解决办法如下: 找到   C:\Users\Administrator(你的用户名)\.android\avd\mm.adv( ...