zoukankan      html  css  js  c++  java
  • UVA1660 Cable TV Network (无向图的点连通度)

    题意:求一个无向图的点连通度。

    把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次。最大流求最小割即可。

    一些细节的东西:1.源点固定,汇点要枚举一遍,因为最小割割断以后会形成连通分量,在分割以后那个连通分量里的割会更大。

    2.每次枚举重建一下图。3.从入点进,出点出,才认为是经过了一个原来的点,那么源点和汇点是不必经过的,所以一个在出点,另外一个枚举入点。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 102;
    
    struct Edge
    {
        int v,cap,nxt;
    };
    
    vector<Edge> E;
    vector<Edge> bak;
    #define PB push_back
    
    int head[maxn];
    
    void AddEdge(int u,int v,int c)
    {
        bak.PB({v,c,head[u]});
        head[u] = bak.size()-1;
        bak.PB({u,0,head[v]});
        head[v] = bak.size()-1;
    }
    
    int S,T,cur[maxn],d[maxn],q[maxn];
    
    bool bfs()
    {
        memset(d,0,sizeof(d));
        int l = 0, r = 0;
        q[r++] = S; d[S] = 1;
        while(r>l){
            int u = q[l++];
            for(int i = head[u]; ~i; i = E[i].nxt){
                Edge &e = E[i];
                if(!d[e.v] && e.cap>0){
                    d[e.v] = d[u] + 1;
                    q[r++] = e.v;
                }
            }
        }
        return d[T];
    }
    
    int dfs(int u,int a)
    {
        if(u == T||!a) return a;
        int flow = 0,f;
        for(int &i = cur[u]; ~i; i = E[i].nxt){
            Edge &e = E[i];
            if(d[e.v] == d[u]+1 && (f = dfs(e.v,min(a,e.cap)))>0){
                flow += f; a -= f;
                e.cap -= f; E[i^1].cap += f;
                if(!a) break;
            }
        }
        return flow;
    }
    
    const int INF = 0x3f3f3f3f;
    
    int MaxFlow()
    {
        int flow = 0;
        while(bfs()){
            memcpy(cur,head,sizeof(head));
            flow += dfs(S,INF);
        }
        return flow;
    }
    int n,m;
    
    void init()
    {
        memset(head,-1,sizeof(head));
        bak.clear();
    }
    
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&n,&m)){
            init();
            for(int i = 1; i < n; i++) AddEdge(i,i+n,1);
            for(int i = 0; i < m; i++){
                int u,v; scanf(" (%d,%d)",&u,&v);
                AddEdge(u+n,v,INF); AddEdge(v+n,u,INF);
            }
            int ans = n;
            S = n;
            for(T = 1; T < n; T++){
                E = bak;
                ans = min(ans,MaxFlow());
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    PAT (Advanced Level) 1060. Are They Equal (25)
    PAT (Advanced Level) 1059. Prime Factors (25)
    PAT (Advanced Level) 1058. A+B in Hogwarts (20)
    PAT (Advanced Level) 1057. Stack (30)
    PAT (Advanced Level) 1056. Mice and Rice (25)
    PAT (Advanced Level) 1055. The World's Richest (25)
    PAT (Advanced Level) 1054. The Dominant Color (20)
    PAT (Advanced Level) 1053. Path of Equal Weight (30)
    PAT (Advanced Level) 1052. Linked List Sorting (25)
    PAT (Advanced Level) 1051. Pop Sequence (25)
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4768038.html
Copyright © 2011-2022 走看看