zoukankan      html  css  js  c++  java
  • POJ

    题意:求一个无向图的点连通度。点联通度是指,一张图最少删掉几个点使该图不连通;若本身是非连通图,则点连通度为0。
    分析:无向图的点连通度可以转化为最大流解决。方法是:1.任意选择一个点作为源点;2.枚举所有与该点间没有边的点作为汇点;3.将每个点拆为入点和出点,入点到出点建一条流量为1的边;4.原本有边关系的两点,建流量为正无穷的双向边;5.每次跑出最大流,其中最小值即点连通度,若最小值为正无穷,则说明点连通度为|顶点数|。

    #include<iostream>
    #include<cstring>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int maxn = 1e2+5;
    
    bool vis[maxn];
    struct Edge{
        int from, to,cap,flow; 
    };
    struct Dinic
    {
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
    
        void init(int n){
            this->n = n;
            for(int i=0;i<=n;++i){
                G[i].clear();
            }
            edges.clear();
        }
    
        void 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);
        }
    
        bool BFS(){
            memset(vis,0,sizeof(vis));
            queue<int> q;
            q.push(s);
            d[s] = 0;
            vis[s] = 1;
            while(!q.empty()){
                int x = q.front(); q.pop();
                for(int i=0;i<G[x].size();i++){
                    Edge &e = edges[G[x][i]];
                    if(!vis[e.to] && e.flow < e.cap){
                        vis[e.to] = 1;
                        d[e.to] = d[x] + 1;//层次图
                        q.push(e.to);
                    }
                }
            }
            return vis[t];//能否到汇点,不能就结束
        }
        int DFS(int x,int a)//x为当前节点,a为当前最小残量
        {
            if(x == t || a == 0) return a;
            int flow = 0 , r;
            for(int& i = cur[x];i < G[x].size();i++){
                Edge& e = edges[G[x][i]];
                if(d[x] + 1 == d[e.to] && (r = DFS(e.to , min(a,e.cap - e.flow) ) ) > 0 ){
                    e.flow += r;
                    edges[G[x][i] ^ 1].flow -= r;
                    flow += r;//累加流量
                    a -= r;
                    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;
        }
    }F;
    
    int G[maxn][maxn];
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int N,M;
        while(scanf("%d %d",&N,&M)==2){
            int u,v,st=N;                   //任选一点为源点,此处选择0
            for(int i=0;i<N;++i){
                G[i][i] = 1;
                for(int j=i+1;j<N;++j)
                    G[i][j] = G[j][i] = 0;
            }
            for(int i=1;i<=M;++i){
                scanf(" (%d,%d)",&u,&v);
                G[u][v] = G[v][u] = 1;
            }
            int ans = INF;
            for(int i=0;i<N;++i){          //枚举汇点
                if(G[0][i]) continue;
                F.init(2*N);
                for(int j=0;j<N;++j){
                    F.AddEdge(j,j+N,1);     //拆点 [0,N-1]为入点,[N,2N-1]为出点
                }
                for(int j=0;j<N;++j){
                    for(int k=j+1;k<N;++k){
                        if(G[j][k]){
                            F.AddEdge(j+N,k,INF);
                            F.AddEdge(k+N,j,INF);
                        }
                    }
                }
                ans = min(ans,F.MaxFlow(st,i));
            }
            if(ans==INF) ans = N;
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    为了更好的明天
  • 相关阅读:
    Python开发WebService--使用soaplib库
    weblogic
    cronttab命令
    redhat下配置VNC远程客户端连接
    Linux主机名域名修改问题
    使用expdp命令自动备份数据库
    Linux下内存管理
    Linux下用户和用户组管理
    虚拟机上安装vmware tool
    linux基本信息查询
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9538363.html
Copyright © 2011-2022 走看看