zoukankan      html  css  js  c++  java
  • (网络流 模板)A Plug for UNIX -- poj -- 1087

    链接:

    http://poj.org/problem?id=1087

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/C

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#problem/J (密码:0817)

    n个插座,m个电器及其对应的插座,k个转化器,前一个插座可以转化为后一个插座,问最少有多少设备没有插座用,转换器数量不限
    最大流,源点向插座建边,容量为1,电器向汇点建边,容量为1,相应的插座和电器连边,容量为1,前一个插座转化为后一个插座,
    后一个插座向前一个插座建边,容量为无穷大,求得的最大流即为最多配对的电器。

    网络流的部分是会了, 可是如何建图还是要学习

    代码:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    
    #define N 1005
    #define INF 0xfffffff
    
    int G[N][N], Layer[N];
    char s[N][50];
    
    bool CanLine(char s1[], char s2[]) ///判断转接口是否相同
    {
        if(strcmp(s1, s2)==0)
            return true;
        return false;
    }
    
    bool BFS(int Start, int End)
    {
        queue<int>Q;
        Q.push(Start);
    
        memset(Layer, -1, sizeof(Layer));
        Layer[Start] = 0;
    
        while(Q.size())
        {
            int u = Q.front();
            Q.pop();
    
            if(u==End) return true;
    
            for(int i=1; i<=End; i++)
            {
                if(Layer[i]==-1 && G[u][i])
                {
                    Layer[i] = Layer[u] + 1;
                    Q.push(i);
                }
            }
        }
        return false;
    }
    int DFS(int u, int MaxFlow, int End)
    {
        if(u==End) return MaxFlow;
    
        int uflow = 0;
    
        for(int i=1; i<=End; i++)
        {
            if(G[u][i] && Layer[i]==Layer[u]+1)
            {
                int flow = min(G[u][i], MaxFlow-uflow);
                flow = DFS(i, flow, End);
    
                G[u][i] -= flow;
                G[i][u] += flow;
                uflow += flow;
    
                if(uflow == MaxFlow) break;
            }
        }
    
        return uflow;
    }
    int Dinic(int Start, int End)
    {
        int MaxFlow = 0;
    
        while(BFS(Start, End))
            MaxFlow += DFS(Start, INF, End);
    
        return MaxFlow;
    }
    
    
    int main()
    {
        int n, m, k;
    
        while(scanf("%d", &n)!=EOF)
        {
            int i, j;
    
            memset(G, 0, sizeof(G));
    
            for(i=1; i<=n; i++) ///插头从1~n
                scanf("%s", s[i]);
    
            scanf("%d", &m);
            for(i=1; i<=m; i++) ///手机从n~n+m, 忽略手机的名字
                scanf("%*s%s", s[i+n]);
    
            scanf("%d", &k);
    
            ///Ki是转换头进入的开始点, Kj是转换头出去的开始点, Start是源点,End是汇点
            int Ki = n+m, Kj = Ki+k, Start = Kj+k+1, End = Start+1;
            for(i=1; i<=k; i++) ///转换器的进入n+m~n+m+k, 转换器的出从n+m+k~n+m+2*k
            {
                ///把入和出连接
                scanf("%s%s", s[Ki+i], s[Kj+i]);
                G[Ki+i][Kj+i] = INF; ///转换器无限提供
            }
    
            for(i=1; i<=m; i++) ///建立手机和转换器,插座的关系
            {
                for(j=1; j<=n; j++) ///匹配一下手机和插座是否直接可以相连
                    if(CanLine(s[i+n], s[j]))
                        G[i+n][j]=true;
    
                for(j=1; j<=k; j++) ///匹配一下手机和转换器入是否可以相连
                    if(CanLine(s[i+n], s[Ki+j]))
                        G[i+n][Ki+j]=true;
            }
    
            for(i=1; i<=k; i++) ///建立转换器与转换器,插座的关系
            {
                for(j=1; j<=k; j++) /// 匹配转换器与转换器入,转换器无限提供, 直接最大值
                    if(i!=j && CanLine(s[Kj+i], s[Ki+j]))
                        G[Kj+i][Ki+j] = INF;
    
                for(j=1; j<=n; j++) /// 匹配转换器出和插座的关系
                    if(CanLine(s[Kj+i], s[j])==true)
                        G[Kj+i][j] = true;
            }
    
            for(i=1; i<=m; i++) ///源点与手机的关系
                G[Start][n+i] = true;
    
            for(i=1; i<=n; i++) ///插座与汇点的关系
                G[i][End] = true;
    
            printf("%d
    ", m-Dinic(Start, End));
        }
    
        return 0;
    }
    勿忘初心
  • 相关阅读:
    python模块:XML
    python常用模块:json&pickle
    python模块:os,sys
    python常用模块:time与random
    文件查询修改功能实现
    Ubuntu--smb配置文件详解
    Ubuntu添加计划任务
    Docker私有仓库registry
    docker + calico网络,实现不同容器之间的相互访问
    Centos7 yum安装nginx
  • 原文地址:https://www.cnblogs.com/YY56/p/4737839.html
Copyright © 2011-2022 走看看