poj 1087 A Plug for UNIX 二分图最大匹配

来源:互联网 发布:品茗标书制作软件 编辑:程序博客网 时间:2024/05/01 19:10

题意:

给n个插座和m个设备,每个设备只能接特定的插头,另外给k个适配器,每个适配器有两个参数:插座类型和插头类型,各个适配器间可互联且适配器使用不限。求不能接通的最小设备数。

思路:

对设备器可转换矩阵用floyd算法求闭包。然后对插座集和设备集进行二分图最大匹配。

代码:

#include <iostream>#include <map>#include <string>using namespace std;const int maxN=1024; int M,v1,v2;bool g[maxN][maxN];bool vis[maxN];int link[maxN];int plug[maxN];int notExist[maxN];int adapter[maxN][maxN];bool dfs(int x){for(int y=1;y<=v2;++y)if(g[x][y]&&!vis[y]){vis[y]=true;if(link[y]==0||dfs(link[y])){link[y]=x;return true;}}return false;}void hungary(){for(int x=1;x<=v1;++x){memset(vis,false,sizeof(vis));if(dfs(x))++M;}return ;}int main(){int i,j,n,m,k;map<string,int> receptacle,device;string a,b;scanf("%d",&n);for(i=1;i<=n;++i){cin>>a;receptacle[a]=i;}memset(notExist,0,sizeof(notExist));scanf("%d",&m);for(i=1;i<=m;++i){cin>>a>>b;device[a]=i;if(receptacle[b]==0){receptacle[b]=++n; notExist[n]=1;plug[i]=n;}elseplug[i]=receptacle[b];}memset(adapter,0,sizeof(adapter));scanf("%d",&k);for(i=1;i<=k;++i){cin>>a>>b;if(receptacle[a]==0){receptacle[a]=++n;notExist[n]=1;}if(receptacle[b]==0){receptacle[b]=++n;notExist[n]=1;}adapter[receptacle[a]][receptacle[b]]=1;}for(k=1;k<=n;++k)adapter[k][k]=1;for(k=1;k<=n;++k)for(i=1;i<=n;++i)for(j=1;j<=n;++j)if(adapter[i][k]==1&&adapter[k][j]==1)adapter[i][j]=1;v1=n;v2=m;M=0;memset(g,false,sizeof(g));memset(link,0,sizeof(link));for(i=1;i<=n;++i)for(j=1;j<=m;++j){int x=plug[j];if(adapter[x][i]==1&¬Exist[i]==0)g[i][j]=1;}hungary();printf("%d",m-M);}


0 0
原创粉丝点击