POJ 1087 A Plug for UNIX【二分图最大匹配】

题意: 已知有n个插头,知道了m个用电器和其能插的插座型号,和k个转换器,问最少有多少个用电器无法连接到相应的插座上。

         适配器的作用:

         例如:有插座 C

                 转换器 B(插孔)  C(插头) 

                 如果用电器能插到插座B上,那么通过转换器,它就能插到C上。

分析: 建图的时候递归建图,如果用电器能直接连到某个插座或通过转换器间接查到某个插座上,就在期间连一条边,求出最大匹配,用总数减去即为剩下的无法连接个数的最小值

 

#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
using namespace std;
#define clr(x)memset(x,0,sizeof(x))
struct node
{
    int to,next;
}e[100000];
int tot;
int head[300];
void add(int s,int u)
{
    e[tot].to=u;
    e[tot].next=head[s];
    head[s]=tot++;
}
int v[300];
int link[300];
int find(int x)
{
    int i,k;
    for(i=head[x];i;i=e[i].next)
    {
        k=e[i].to;
        if(!v[k])
        {
            v[k]=1;
            if(link[k]==0||find(link[k]))
            {
                link[k]=x;
                return 1;
            }
        }
    }
    return 0;
}
struct mach
{
     string s1;
     string s2;
}rec[102],mah[102],adp[102];
int vis[102];
int n,m,K;
void dfs(int r)
{
    int i,j;
    string tmp;
    for(i=1;i<=K;i++)
        if(!vis[i]&&adp[i].s1==mah[r].s2)
        {
            vis[i]=1;
            for(j=1;j<=n;j++)
                if(rec[j].s1==adp[i].s2)
                {
                    add(r,j);
                    tmp=mah[r].s2;
                    mah[r].s2=adp[i].s2;
                    dfs(r);
                    mah[r].s2=tmp;
                }
            tmp=mah[r].s2;
            mah[r].s2=adp[i].s2;
            dfs(r);
            mah[r].s2=tmp;
        }
}
int main()
{
    int res=0,i,j;
    tot=1;
    clr(head);
    clr(link);
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        cin>>rec[i].s1;
    scanf("%d",&m);
    for(i=1;i<=m;i++)
        cin>>mah[i].s1>>mah[i].s2;
    scanf("%d",&K);
    for(i=1;i<=K;i++)
        cin>>adp[i].s1>>adp[i].s2;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=n;j++)
            if(rec[j].s1==mah[i].s2)
                add(i,j);
        clr(vis);
        dfs(i);
    }
    res=0;
    for(i=1;i<=m;i++)
    {
        clr(v);
        if(find(i))
            res++;
    }
    printf("%d\n",m-res);
    return 0;
}

 

posted @ 2012-08-13 11:57  'wind  阅读(351)  评论(0编辑  收藏  举报