zoj 1157 || poj 1087 A Plug for UNIX

    技术2022-05-20  63

    最大二分匹配,建图真繁琐!!!

     

    读题读了半天。。。

     

    大意是,一些设备需要固定型号的插座,有的插座可以通过另一种设备得到。

     

    比如样例

     

     

    laptop B 

    phone C 

    pager B 

    clock B 

    comb X 

    B X 

    X A 

    X D 

     

     

    有ABCD四种插座,其中comb的插头是X型号的,而A,D上有X型号的插孔,所以相当于,comb可以和A,D相连。

     

    建图后,用floyd把所有点能连通的都连下,然后匈牙利算法即可。

     

    当然不在已知插座里的插座肯定是不能用的。

     

    有几个小崩溃的点,第二部分输入中,可以输入第一部分没有的插座。第三部分输入中,可以输入第一、第二部分都没有的插座,但是不能忽略他们,因为可能需要靠他们把出现在第一部分的插座给连起来 = =。。。这点纠结了很久,最后测了数据才测出来,悲剧!!!

     

    第一部分和第二部分的名字是没有重复的。

     

    P.S:poj输入格式和zoj不一样。。。

     

    #include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 520 using namespace std; char ch[MAX][30]; int map[MAX][MAX]; char str[MAX][30]; char adp[30]; int used[MAX],mat[MAX]; int n,m,nn; int Augement(int x) { int i; for(i=m+1; i<=m+nn; i++) if( !used[i] && map[x][i] ) { used[i] = 1; if( !mat[i] || Augement(mat[i]) ) { mat[i] = x; return 1; } } return 0; } int Hungary() { int i,sum = 0; memset(mat,0,sizeof(mat)); for(i=1; i<=m; i++) { memset(used,0,sizeof(used)); if( Augement(i) ) sum++; } return sum; } int main() { int ncases; int i,k,p,j; char a[30],b[30]; scanf("%d",&ncases); while( ncases-- ) { scanf("%d",&n); memset(map,0,sizeof(map)); for(i=1; i<=n; i++) scanf("%s",ch[i]); nn = n; scanf("%d",&m); for(i=1; i<=m; i++) { scanf("%s %s",str[i],adp); int flag = 0; for(k=1; k<=n; k++) if( strcmp(adp,ch[k]) == 0 ) { flag = 1; map[i][k+m] = 1; break; } if( flag == 0 ) { n++; memcpy(ch[n],adp,sizeof(adp)); map[i][m+n] = 1; } } scanf("%d",&p); while( p-- ) { scanf("%s %s",a,b); int tmpb = -1,tmpa = -1; for(i=1; i<=n; i++) { if( tmpb != -1 && tmpa != -1 ) break; if( strcmp(b,ch[i]) == 0 ) tmpb = i; if( strcmp(a,ch[i]) == 0 ) tmpa = i; } if( tmpb == -1 ) { n++; memcpy(ch[n],b,sizeof(b)); tmpb = n; } if( tmpa == -1 ) { n++; memcpy(ch[n],a,sizeof(a)); tmpa = n; } map[tmpa+m][tmpb+m] = 1; } for(i=1; i<=m+n; i++) for(k=1; k<=m+n; k++) for(j=1; j<=m+n; j++) if( map[k][i] && map[i][j] && !map[k][j] ) map[k][j] = 1; int ans = Hungary(); printf("%d/n",m-ans); if( ncases ) printf("/n"); } return 0; }  


    最新回复(0)