HDU1498 二分匹配+最大顶点覆盖

题意:给定一张图,图中的每个数代表一种颜色的气球

求:哪种颜色的气球不能在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 }
keep moving...
原文地址:https://www.cnblogs.com/xxx0624/p/2914424.html