您的位置:首页 > 其它

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

2012-08-13 11:57 435 查看
题意: 已知有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: