zoukankan      html  css  js  c++  java
  • USACO Section 5.4 TeleCowmunication(最小割)

    挺裸的一道最小割。把每台电脑拆成一条容量为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 ",ans.size());
    printf("%d",ans[0]);
    Rep(i,1,ans.size()) printf(" %d",ans[i]);
    printf(" ");
    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 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 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+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 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
  • 相关阅读:
    js 点击列表li,获得当前li的id
    PHP松散比较与严格比较的区别详解
    电赛总结(二)——AD芯片总结之AD7705
    C++Premer Plus学习(五)——函数探幽
    FPGA学习
    AD7715
    电赛初探(二)——语音采集回放系统
    MATLAB信号与系统分析(五)——连续时间信号的频谱分析
    MATLAB信号与系统分析(四)——离散信号与系统的复频域分析及MATLAB实现
    MATLAB信号与系统分析(三)——连续信号与系统的复频域分析及MATLAB实现
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4351386.html
Copyright © 2011-2022 走看看