zoukankan      html  css  js  c++  java
  • ACMICPC Live Archive 3031 Cable TV Network

    求解无向图的点连通度,转化为网络流

    详细的解释明天再写了

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define N 60
    #define min(a,b) a<b?a:b
    #define max(a,b) a>b?a:b
    #define INF 0x3f3f3f3f
    
    int first[10*N];
    struct edge
    {
        int u,v,cap,flow,next;
    }e[N*N*N];
    int nume;
    int n,m;
    
    void EK(int s ,int t ,int &MIN)
    {
        int FLOW=0;
        while(1)
        {
            queue<int>q;
            int a[10*N];
            int p[10*N];
            memset(a,0,sizeof(a));
            memset(p,-1,sizeof(p));
            a[s]=INF;
            while(!q.empty()) q.pop();
            q.push(s);
            while(!q.empty())
            {
                int u,v,cap,flow;
                u=q.front(); 
                q.pop();
                for(int k=first[u]; k!=-1; k=e[k].next)
                {
                    v=e[k].v; cap=e[k].cap; flow=e[k].flow;
                    if(!a[v] && cap>flow) //未访问且可增流
                    {
                        a[v]=min(a[u] , cap-flow);
                        p[v]=k;
                        q.push(v);
                    }
                }
            }
            if(!a[t]) break; //不可增广
            for(int k=p[t]; k!=-1; k=p[e[k].u])
            {
                e[k].flow += a[t];
                e[k^1].flow -= a[t];
            }
            FLOW += a[t];
        }
        MIN=min(MIN,FLOW);
    }
    
    void init()
    {
        for(int i=0; i<nume; i++) e[i].flow=0;
    }
    
    void solve(int s)
    {
        int MIN=INF;
        for(int t=1; t<n; t++)//枚举汇点
        {
            EK(s,t,MIN);
            init();
        }
        if(MIN>=INF) printf("%d\n",n);
        else         printf("%d\n",MIN);
    }
    
    void add(int u ,int v , int cap)
    {
        e[nume].u=u; e[nume].v=v; e[nume].cap=cap; e[nume].flow=0;
        e[nume].next=first[u]; first[u]=nume++;
    
        e[nume].u=v; e[nume].v=u; e[nume].cap=0; e[nume].flow=0;
        e[nume].next=first[v]; first[v]=nume++;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(m==0)
            {
                if(n==1)printf("1\n");
                else    printf("0\n");
                continue;
            }
            memset(first,-1,sizeof(first));
            nume=0;
            for(int i=0; i<n; i++) 
                add(i,i+n,1);
            for(int i=0; i<m; i++)
            {
                int u,v; char s[20];
                scanf("%s",s);
                sscanf(s+1,"%d",&u);
                for(int j=0; s[j]!='\0'; j++) if(s[j]==',')
                { sscanf(s+j+1,"%d",&v); break;}
                //拆点,拆为u,u+n,
                add(u+n,v,INF); 
                add(v+n,u,INF);
            }
            solve(n);
        }
        return 0;
    }
  • 相关阅读:
    Linux_LEMP
    Linux_LEMP
    Linux_指令杂烩
    Linux_指令杂烩
    Linux_SELinux使用
    AWS S3存储基于Hadoop之上的一致性保证
    Ozone数据写入过程分析
    Ozone Datanode的分布式元数据管理
    聊聊Ozone的Topology Awareness
    Ozone数据探查服务Recon的启用
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2991173.html
Copyright © 2011-2022 走看看