您的位置:首页 > 其它

POJ 1087&&HDU 1526 A Plug for UNIX (二分图+Floyd传递闭包 )

2015-10-14 21:49 369 查看
   题目大意: 有n个插座,下边n行分为为插座的类型,m个电器,m行分别代表电器的名称和插头的类型.

最后,有k行数据每组,对应适配器的插座和插头的类型.

   思路:将所有的插座,插头编上序号,同时给自己也要标记上插座和插头(均是自身和自身间的关系),然

后给,适配器的插座和插头建立联系.之后进行Floyd的传递闭包链接有间接性关系图.最后匹配,但注意

要进行"编号"与"编号"之间的匹配.

4
A
B
C
D
5
laptop B
phone C
pager B
clock B
comb X
3
B X
X A
X D


#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
int n,m,cro[1000],s,re[1000],gs[1000];
bool Map[1000][1000],use[1000];
char a[1000],b[1000];
void Floyd()
{int i,j,k;
for(k=1;k<s;k++)
for(i=1;i<s;i++)
for(j=1;j<s;j++)
if(Map[i][k]&&Map[k][j])
Map[i][j]=true;
}
int DFS(int v)
{int i,j,k;
for(i=1;i<=n;i++)
if(!use[re[i] ]&&Map[gs[v]][re[i] ])
{
use[re[i] ]=true;
if(cro[re[i] ]==-1||DFS(cro[ re[i] ] ))
{
cro[re[i] ]=v;
return 1;
}
}
return 0;
}
int main()
{int i,j,k;
map<string,int>K;
while(~scanf("%d",&n))
{
getchar();
K.clear();s=1;memset(cro,-1,sizeof(cro));memset(Map,false,sizeof(Map));
for(i=1;i<=n;i++)
{
scanf("%s",a);
if(!K[a]) K[a]=s++;
re[i]=K[a];
Map[re[i]][re[i]]=true;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%s %s",a,b);
if(!K[b]) K[b]=s++;
gs[i]=K[b];
Map[K[b] ][K[b] ]=true;
}
scanf("%d",&k);getchar();
for(i=1;i<=k;i++)
{
scanf("%s %s",a,b);
if(!K[a]) K[a]=s++;
if(!K[b]) K[b]=s++;
Map[K[a]][K[b]]=true;
}
Floyd();
int ans=0;
for(i=1;i<=m;i++)
{memset(use,false,sizeof(use));
ans+=DFS(i);
}
cout<<m-ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分图