• UVA-1660 Cable TV Network (最小割)


    题目大意:给一张n个点、m条边的无向图,求最小点割集的基数。

    题目分析:求无向图最小点割集的基数可以变成求最小割。考虑单源s单汇t的无向图,如果要求一个最小点集,使得去掉这个点集后图不再连通(连通分量数目增多),只需将每个点拆成两个(入点和出点),并且之间连一条容量为1的弧,其他弧不变,在新网络上求最小割便得到这个最小点集的基数。但是本题无源无汇,可以指定一个点作为源点,枚举其它的点作为汇点,求得n-1个点集基数,取最小的便是答案。要注意每次枚举都要重新建图。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int INF=1<<30;
    const int maxn=105;
    
    struct Edge
    {
        int fr,to,cap,fw;
        Edge(int fr,int to,int cap,int fw){
            this->fr=fr;
            this->to=to;
            this->cap=cap;
            this->fw=fw;
        }
    };
    struct Dinic
    {
        vector<Edge>edges;
        vector<int>G[maxn];
        int d[maxn],cur[maxn];
        int vis[maxn],n,s,t;
    
        void init(int n)
        {
            this->n=n;
            edges.clear();
            for(int i=0;i<n;++i) G[i].clear();
        }
    
        void addEdge(int u,int v,int cap)
        {
            edges.push_back(Edge(u,v,cap,0));
            edges.push_back(Edge(v,u,0,0));
            int m=edges.size();
            G[u].push_back(m-2);
            G[v].push_back(m-1);
        }
    
        bool bfs()
        {
            memset(vis,0,sizeof(vis));
            vis[s]=1;
            d[s]=0;
            queue<int>q;
            q.push(s);
            while(!q.empty())
            {
                int u=q.front();
                q.pop();
                for(int i=0;i<G[u].size();++i){
                    Edge& e=edges[G[u][i]];
                    if(e.cap>e.fw&&!vis[e.to]){
                        vis[e.to]=1;
                        d[e.to]=d[u]+1;
                        q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
    
        int dfs(int u,int a)
        {
            if(u==t||a==0) return a;
            int flow=0,f;
            for(int &i=cur[u];i<G[u].size();++i){
                Edge& e=edges[G[u][i]];
                if(d[e.to]==d[u]+1&&(f=dfs(e.to,min(a,e.cap-e.fw)))>0){
                    e.fw+=f;
                    edges[G[u][i]^1].fw-=f;
                    flow+=f;
                    a-=f;
                    if(a==0) break;
                }
            }
            return flow;
        }
    
        int maxFlow(int s,int t)
        {
            this->s=s,this->t=t;
            int flow=0;
            while(bfs()){
                memset(cur,0,sizeof(cur));
                flow+=dfs(s,INF);
            }
            return flow;
        }
    };
    Dinic solver;
    string p;
    int n,m,mark[55];
    vector<Edge>E;
    
    void addEdge(int u,int v,int cap)
    {
        E.push_back(Edge(u,v,cap,0));
    }
    
    void solve()
    {
        int len=p.size(),pos;
        for(pos=0;pos<len;++pos)
            if(p[pos]==',') break;
        int a=0,b=0;
        for(int i=1;i<pos;++i)
            a=a*10+p[i]-'0';
        for(int i=pos+1;i<len-1;++i)
            b=b*10+p[i]-'0';
        addEdge(a<<1|1,b<<1,INF);
        addEdge(b<<1|1,a<<1,INF);
    }
    
    void look()
    {
        for(int i=0;i<solver.edges.size();++i){
            Edge& e=solver.edges[i];
            cout<<e.fr<<' '<<e.to<<' '<<e.cap<<' '<<e.fw<<endl;
        }
    }
    
    int main()
    {
        int a,b;
        while(~scanf("%d%d",&n,&m))
        {
            E.clear();
            for(int i=0;i<n;++i) addEdge(i<<1,i<<1|1,1);
            while(m--)
            {
                cin>>p;
                solve();
            }
            //look();
            int ans=n,k=E.size();
            for(int i=1;i<n;++i){
                solver.init(n*2);
                for(int j=0;j<k;++j){
                    solver.addEdge(E[j].fr,E[j].to,E[j].cap);
                }
                int flow=solver.maxFlow(1,i<<1);
                ans=min(ans,flow);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    C#基础之事件
    C#中IQueryable和IEnumerable的区别(2)
    读取不到appsettings.json的值
    【PHP】 延时跳转
    【canvas】 绘制七巧板
    小程序项目编译失败问提解决
    windows下安装node.js
    deskgenius分区失败,分区消失,解决的过程
    IOS:重写UISlider大小解决UISlider滑动不灵敏的问题
    IOS:reason: 'invalid nib registered for identifier (PhotoCellID)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5117459.html
Copyright © 2020-2023  润新知