您的位置:首页 > 其它

POJ 1087 A Plug for UNIX

2012-11-11 12:45 363 查看
二分图匹配,主要在于建图,貌似建得有点丑。。把能插座X上能插入的插头(包括通过转化器的)通过dfs全找出来,图就建好了,我是用map将字符串映射成数组下标的。

二分图一边是插座,一边是插头。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>

using namespace std;

const int maxN=110;
map<string,int> ind;
int n,m,k,cnt,link[maxN];
string plug[maxN],rec[maxN],name,s1,s2;
bool G[maxN*10][maxN*10],g[maxN*10][maxN*10],used[maxN],vis[maxN*10];

void build(int i,int u){
for(int v=0;v<cnt;v++)
if(G[u][v]&&!vis[v]){
g[i][v]=true;
vis[v]=true;
build(i,v);
}
}

bool dfs(int u){
for(int v=0;v<n;v++){
int uu=ind[plug[u]],vv=ind[rec[v]];
if(g[vv][uu]&&!used[v]){
used[v]=true;
if(link[v]==-1||dfs(link[v])){
link[v]=u;
return true;
}
}
}
return false;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
while(cin>>n){
cnt=0;
memset(G,false,sizeof(G));
memset(g,false,sizeof(g));
for(int i=0;i<maxN*10;i++) G[i][i]=true;
for(int i=0;i<n;i++){
cin>>rec[i];
if(!ind.count(rec[i])) ind[rec[i]]=cnt++;
}
cin>>m;
for(int i=0;i<m;i++){
cin>>name>>plug[i];
if(!ind.count(plug[i])) ind[plug[i]]=cnt++;
}
cin>>k;
for(int i=0;i<k;i++){
cin>>s1>>s2;
if(!ind.count(s1)) ind[s1]=cnt++;
if(!ind.count(s2)) ind[s2]=cnt++;
G[ind[s2]][ind[s1]]=true;
}
for(int i=0;i<cnt;i++){
memset(vis,false,sizeof(vis));
build(i,i);
}
//for(int i=0;i<cnt;i++){
//  for(int j=0;j<cnt;j++)
//    cout<<g[i][j]<<' ';
//cout<<endl;
//}
memset(link,-1,sizeof(link));
int res=0;
for(int i=0;i<m;i++){
memset(used,false,sizeof(used));
if(dfs(i)) res++;
}
cout<<m-res<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: