POJ 1087 A Plug for UNIX

时间:2022-05-19 22:01:56
题目大意:
给你一些插头,插座和转换器。问最多有几个插头能插上去。
输入数:
先是一个n,代表有n个插座,然后是一个m,代表有m个插头。然后有p种类型的转换器,转换器的数量是无限的。
代表可以把A插头变为B插头。
====================================================================================================
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
typedef long long LL;
const int INF = 1e9+7;
const int maxn = 2005;
const int MOD = 1e9+7;
int G[maxn][maxn], Layer[maxn];
char str[maxn][30];

bool BFS(int Star, int End)
{
    memset(Layer, 0, sizeof(Layer));
    queue<int> Q;

    Layer[Star] = 1;
    Q.push(Star);

    while( Q.size() )
    {
        int s = Q.front();
        Q.pop();
        if(s == End) return true;
        for(int i=0; i<= End; i++)
        {
            if(!Layer[i] && G[s][i] )
            {
                Q.push(i);
                Layer[i] = Layer[s] + 1;
            }
        }
    }
    return false;
}

int DFS(int Star, int End, int MaxFlow)
{
    if(Star == End) return MaxFlow;

    int sFlow = 0;
    for(int i=0;i <= End; i++)
    {
        int flow = G[Star][i];
        if( !(Layer[i] == Layer[Star] + 1 && flow) )
            continue;

        flow = min(MaxFlow-sFlow, flow);
        flow = DFS(i, End, flow);

        G[Star][i] -= flow;
        G[i][Star] += flow;
        sFlow += flow;

        if(sFlow == MaxFlow)
            break;
    }
    if(sFlow == 0)
        Layer[Star] = 0;

    return sFlow;
}

int Dinic(int Star,int End)
{
    int ans = 0;
    while( BFS(Star, End) )
    {
        ans += DFS(Star, End, INF);
    }
    return ans;
}


int main()
{
    int n, m, p;
    while(scanf("%d", &n) != EOF)
    {
        memset(G, 0, sizeof(G));

        for(int i=1; i<=n; i++)///插座
            scanf("%s", str[i]);

        scanf("%d", &m);
        for(int i=n+1; i<=n+m; i++)///插头
        {///插头和源点的关系
            scanf("%*s%s", str[i]);
            G[0][i] = 1;
        }

        scanf("%d", &p);
        for(int i=n+m+1; i<=n+m+p; i++)///转换器
        {
            scanf("%s %s", str[i], str[i+p]);
            G[i][i+p] = INF;///转换器之间的关系
        }
        int Star = 0, End = n+m+2*p+1;

        for(int i=1; i<=n; i++)///插座和汇点的关系
            G[i][End] = 1;

        for(int i=n+1; i <= n+m; i ++)///插头和转换器的关系
        {
            for(int j=n+m+1; j<=n+m+p; j++)
            {
                if(strcmp(str[i], str[j]) == 0)
                    G[i][j] = INF;
            }
        }

        for(int i=n+1; i<=n+m; i++)///插头和插座的关系
        {
            for(int j=1; j<=n; j++)
            {
                if(strcmp(str[i], str[j]) == 0)
                    G[i][j] = INF;
            }
        }

        for(int i=n+m+p+1; i<=n+m+p+p; i++)///转换器和插座的关系
        {
            for(int j=1; j<=n; j++)
            {
                if(strcmp(str[i], str[j]) == 0)
                    G[i][j] = INF;
            }
        }

        for(int i=n+m+p+1; i<=n+m+p+p; i++)///转换器和转换器的关系
        {
            for(int j=n+m+1; j<=n+m+p; j++)
            {
                if(strcmp(str[i], str[j]) == 0)
                    G[i][j] = INF;
            }
        }


        int ans = m - Dinic(Star, End);


        printf("%d\n", ans);
    }
    return 0;
}