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 }

 

你可能感兴趣的:(HDU)