poj1087

来源:互联网 发布:大麦盒子怎么设置网络 编辑:程序博客网 时间:2024/05/21 10:46

#include <iostream>
#include <map>
#include <string>
#include <cstring>
#define N 1000
#define ND 1000

using namespace std;
/* nl, nr是二分图左右节点的数量 , dev[]中存储了每个设备对应的插头的id*/
int g[N][N], linkable[N][N], v[N], visited[N], nr, nl;
int dev[ND];

map<string, int> lst_plug;

/* 这个是用来求二分图最大匹配的算法 */
int dfs(int t)
{
    int i;
    for (i = 1; i <= nr; i++)
    {
        if (!v[i] && g[t][i])
        {
            v[i] = 1;
            if (visited[i] == -1 || dfs(visited[i]))
            {
                visited[i] = t;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    /*nap为可用的插头的数目*/
    int n1, nd, np = 1, i, j, nap, ans = 0;
    string str1, str2;
    cin >> n1;
    nap = n1;
    /*对于每个插头,都分配一个id给他,并存储入map表之中*/
    for (i = 0; i < n1; i++)
    {
        cin >> str1;
        lst_plug[str1] = np++;
    }
    cin >> nd;
    for (i = 1; i <= nd; i++)
    {
        cin >> str1 >> str2;
        if (!lst_plug[str2])
            lst_plug[str2] = np++;
        dev[i]= lst_plug[str2];
    }
    cin >> n1;
    memset(linkable, 0, sizeof(linkable));
    for (i = 0; i < n1; i++)
    {
        int a, b;
        cin >> str1 >> str2;
        if (!lst_plug[str2])
            lst_plug[str2] = np++;
        if (!lst_plug[str1])
            lst_plug[str1] = np++;
        a = lst_plug[str1], b = lst_plug[str2];
        linkable[a][b] = 1;
    }
    np--;
    /* 使用传递闭包的方法检查节点之间的可访问性    */
    for (i = 1; i <= np; i++)
        linkable[i][i] = 1;
    for (int k = 1; k <= np; k++)
        for (i = 1; i <= np; i++)
            for (j = 1; j <= np; j++)
                linkable[i][j] = linkable[i][j] || (linkable[i][k]
                        && linkable[k][j]);
    /* 建立二分图 */
    memset(g, 0, sizeof(g));
    for (i = 1; i <= nd; i++)
    {
        int plid = dev[i];
        for (j = 1; j <= nap; j++)
            if (linkable[plid][j])
                g[i][j] = 1;
    }
    /* 求二分图最大匹配 */
    nl = nd;
    nr = nap;
    for (i = 0; i < N; i++)
        visited[i] = -1;
    for (i = 1; i <= nl; i++)
    {
        memset(v, 0, sizeof(v));
        ans += dfs(i);
    }
    printf("%d\n", nd - ans);
    return 0;
}

原创粉丝点击