1. 程式人生 > 其它 >POJ1087 A Plug for UNIX

POJ1087 A Plug for UNIX

題目大意:

有電器和配套的插座,以及每種無限個的裝換插頭

問:最少多少電器用不上電?

畫畫圖,可以知道是一個二分圖,中間結點需要用傳遞閉包優化掉

Floyd+匈牙利演算法(二分圖匹配)

 1 #include<map>
 2 #include<cmath>
 3 #include<queue>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<iostream>
 7 using namespace std;
 8 const int N=800+10;
 9 string
plug,device,plug0,plug1; 10 int n,m,k,g[N][N],match[N],used[N]; 11 void floyd(int sz) { //傳遞閉包 12 for(int k=1; k<=sz; k++) 13 for(int i=1; i<=sz; i++) 14 for(int j=1; j<=sz; j++) 15 g[i][j]|=(g[i][k]&&g[k][j]); 16 } 17 bool dfs(int u) { 18 for
(int i=1; i<=m; i++) 19 if(!used[i]&&g[u][i]) { 20 used[i]=1; 21 if(match[i]==-1||dfs(match[i])) { 22 match[i]=u; 23 return true; 24 } 25 } 26 return false; 27 } 28 int hungary() { 29 int res=0; 30 memset(match,-1
,sizeof(match)); 31 for(int i=m+n+101; i<=m+n+101+n; res+=dfs(i++)) 32 memset(used,0,sizeof(used)); 33 return n-res; 34 } 35 int main() { 36 while(~scanf("%d",&m)) { 37 memset(g,0,sizeof(g)); 38 map<string,int>q0,q1;//q0 for plugs and q1 for devices 39 for(int i=1; i<=m; i++)cin>>plug,q0[plug]=i; 40 scanf("%d",&n); 41 int tmpn=m+n+100,tmpm=m;//100 is the max value of k 42 for(int i=1; i<=n; i++) { 43 cin>>device>>plug; 44 q1[device]=++tmpn; 45 if(!q0[plug]) q0[plug]=++tmpm; 46 g[q1[device]][q0[plug]]=1; 47 } 48 scanf("%d",&k); 49 for(int i=1; i<=k; i++) { 50 cin>>plug0>>plug1; 51 if(!q0[plug0]) q0[plug0]=++tmpm; 52 if(!q0[plug1]) q0[plug1]=++tmpm; 53 g[q0[plug0]][q0[plug1]]=1;//單向傳遞 54 } 55 floyd(tmpn); 56 printf("%d\n",hungary()); 57 } 58 return 0; 59 }