usaco5.4.3 Telecowmunication

来源:互联网 发布:matlab求矩阵的相角 编辑:程序博客网 时间:2024/05/21 08:38

一 原题

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 21 32 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)

13



二 分析

题意:给定一个无向图,起点Start和终点End,求最小点割集。
思路:第一步把点割集转化为边割集,方法是把原图中每个点S分为S_a和S_b两个点,S_a到S_b建立一条容量为1的有向边,原图中相连的两个点S,T,建立两条有向边(S_b->T_a),(T_b->S_a),容量均为无穷大。那么原图中最小点割集的大小就等于现在这个图中从Start_b到End_a的最大流值。
这里在找增广路径时,我一开始用dfs找,结果tle,改成bfs,并注意到每次增光路径增加的流量值都为1,就可以过了。
第二步是要找出点割集中的所有元素,我们依次删掉每个点,看最大流值是否减1,如果是就加入集合,直到最大流值为0。


三 代码

运行结果:
USER: Qi Shen [maxkibb3]TASK: telecowLANG: C++Compiling...Compile: OKExecuting...   Test 1: TEST OK [0.000 secs, 4196 KB]   Test 2: TEST OK [0.000 secs, 4196 KB]   Test 3: TEST OK [0.000 secs, 4196 KB]   Test 4: TEST OK [0.000 secs, 4196 KB]   Test 5: TEST OK [0.000 secs, 4196 KB]   Test 6: TEST OK [0.000 secs, 4196 KB]   Test 7: TEST OK [0.000 secs, 4196 KB]   Test 8: TEST OK [0.011 secs, 4196 KB]   Test 9: TEST OK [0.011 secs, 4196 KB]   Test 10: TEST OK [0.043 secs, 4196 KB]   Test 11: TEST OK [0.054 secs, 4196 KB]All tests OK.

Your program ('telecow') produced all correct answers! This is yoursubmission #3 for this problem. Congratulations!



AC代码:
/*ID:maxkibb3LANG:C++PROB:telecow*/#include<cstdio>#include<map>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int MAXN = 105;const int INF = 1e6;int N, M, C1, C2;int S, T;map<int, int> E[MAXN * 2];map<int, int> Ee[MAXN *2];bool V[MAXN * 2];int From[MAXN * 2];void init() {    freopen("telecow.in", "r", stdin);    freopen("telecow.out", "w", stdout);    scanf("%d%d%d%d", &N, &M, &C1, &C2);    S = 2 * C1;    T = 2 * C2 - 1;    for(int i = 1; i <= N; i++) {        E[2 * i - 1][2 * i] = 1;    }    int s, e;    for(int i = 0; i < M; i++) {        scanf("%d%d", &s, &e);        E[2 * s][2 * e - 1] = INF;        E[2 * e][2 * s - 1] = INF;    }}int bfs() {    queue<int> q;    q.push(S);    while(!q.empty()) {        int id = q.front();        q.pop();        if(id == T) {            while(id != S) {                Ee[From[id]][id]--;                Ee[id][From[id]]++;                id = From[id];            }            return 1;        }        for(map<int, int>::iterator it = Ee[id].begin();            it != Ee[id].end(); it++) {            if(From[it->first] != 0 || it->second == 0) continue;            q.push(it->first);            From[it->first] = id;        }    }    return 0;}int max_flow() {    int ret = 0;    while(true) {        memset(From, 0, sizeof(From));        From[S] = S;        int delta = bfs();        ret += delta;        if(delta == 0) break;    }    return ret;}void copy_graph() {    for(int i = 0; i < MAXN * 2; i++) {        Ee[i].clear();        map<int, int>::iterator it = E[i].begin();        for(;it != E[i].end(); it++)            Ee[i][it->first] = E[i][it->first];    }}void find_cut(int _ans) {    int cans = _ans;    for(int i = 1; i <= N; i++) {        if(i == C1 || i == C2) continue;        E[2 * i - 1][2 * i] = 0;        copy_graph();        int tmp = max_flow();        if(tmp == cans) {            E[2 * i - 1][2 * i] = 1;            continue;        }        if(cans == _ans) printf("%d", i);        else printf(" %d", i);        if(tmp == 0) {            printf("\n");            break;        }        cans--;    }}void solve() {    copy_graph();    int ans = max_flow();    printf("%d\n", ans);    find_cut(ans);}int main() {    init();    solve();    return 0;}


原创粉丝点击