题意:给定一张图,图中的每个数代表一种颜色的气球
求:哪种颜色的气球不能在K次中被消灭( 每次只能消灭一行或者一列 )
二分匹配:按照题意来分析 就是要寻找一种消灭方法 使得所有同种气球被消灭 这就符合了最小点覆盖的意义
当所有的点(在这里也就是气球的行号和列号 ) 被覆盖,也就是所有的行号和列号被覆盖
最小点覆盖=最大匹配
View Code
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<queue> 5 #include<math.h> 6 #include<algorithm> 7 using namespace std; 8 const int maxn = 55; 9 const int maxm = 105; 10 int cnt[ maxn ]; 11 int mat[ maxm ][ maxm ]; 12 void init(){ 13 memset( cnt,0,sizeof( cnt ) ); 14 memset( mat,0,sizeof( mat )); 15 } 16 int n,k; 17 int vis[ maxm ],link[ maxm ]; 18 int dfs( int now,int c ){ 19 //int next; 20 for( int i=1;i<=n;i++ ){ 21 if( vis[ i ]==0&&mat[now][ i ]==c ){ 22 vis[ i ]=1; 23 if( link[ i ]==-1||dfs( link[i],c ) ){ 24 link[ i ]=now; 25 return 1; 26 } 27 } 28 } 29 return 0; 30 } 31 32 int km( int c ){ 33 memset( link,-1,sizeof( link )); 34 int ans=0; 35 for( int i=1;i<=n;i++ ){ 36 memset( vis,0,sizeof( vis )); 37 ans+=dfs( i,c ); 38 } 39 return ans; 40 } 41 42 int main(){ 43 while( scanf("%d%d",&n,&k)==2 ,n+k ){ 44 init(); 45 for( int i=1;i<=n;i++ ){ 46 for( int j=1;j<=n;j++ ){ 47 scanf("%d",&mat[ i ][ j ]); 48 cnt[ mat[i][j] ]++; 49 } 50 } 51 int num[ maxn ]; 52 int CNT=0; 53 for( int i=1;i<=50;i++ ){ 54 if( cnt[ i ]&&km( i )>k ){ 55 num[ CNT ]=i; 56 CNT++; 57 } 58 } 59 if( CNT==0 ) 60 printf("-1\n"); 61 else{ 62 printf("%d",num[0]); 63 for( int i=1;i<CNT;i++ ) 64 printf(" %d",num[ i ]); 65 printf("\n"); 66 } 67 } 68 return 0; 69 }