hdu 1498 50 years, 50 colors(二分匹配,最小点覆盖)

题意:n*n的矩阵放置不同的颜色(不同的数字代表不同的颜色),你有k次选择,每一次只能选择某一行或某一列,可以消除该行(列)的所有颜色,问有哪几种颜色,无论怎样经过k次选择后依然无法完全抹去。

分析:依旧是将横坐标作为x集,纵坐标作为y集合进行匹配。对于某种颜色的匹配,如果他的最大匹配大于k,则该颜色在k次里无论如何都无法抹去的。

         还有一个问题就是为什么这道题是最小点覆盖,通过自己画图就知道了

        假设x{1}和{1,2,3,4}分别连接,x{2}和y{3}连接,则只用选择1,2行,就可以将所有的颜色抹去了

View Code
 1 #include<stdio.h>

 2 #include<string.h>

 3 #include<algorithm>

 4 using namespace std;

 5 const int MAXN=150;

 6 int map[MAXN][MAXN];

 7 int pre[MAXN];

 8 int vis[MAXN];

 9 int used[MAXN];

10 int ans[MAXN];

11 int n,k;

12 

13 bool cmp(int a,int b)

14 {

15     return a<b;

16 }

17 

18 int find(int cur,int color)

19 {

20     int i;

21     for(i=1; i<=n; i++)

22     {

23         if(map[cur][i]==color && !vis[i])//对应的某一列是否存在该color

24         {

25             vis[i]=1;

26             if(pre[i]==-1 || find(pre[i],color))//这里find的是pre【i】,刚开始这里敲错了wa了两次

27             {

28                 pre[i]=cur;

29                 return 1;

30             }

31         }

32     }

33     return 0;

34 }

35 

36 int main()

37 {

38     int i,j,t,w,sum;

39     int len;

40     while(scanf("%d%d",&n,&k))

41     {

42         if(n==0 && k==0) break;

43         memset(map,0,sizeof(map));

44         memset(used,0,sizeof(used));

45 

46         for(i=1; i<=n; i++)

47         {

48             for(j=1; j<=n; j++)

49             {

50                 scanf("%d",&w);

51                 map[i][j]=w;

52             }

53         }

54         len=0;

55         for(i=1; i<=n; i++)

56         {

57             for(j=1; j<=n; j++)

58             {

59                 memset(pre,-1,sizeof(pre));

60                 sum=0;

61                 if(used[map[i][j]]==0)//该颜色没有出现过

62                 {

63                     used[map[i][j]]=1;

64                     for(t=1; t<=n; t++)//枚举每一行

65                     {

66                         memset(vis,0,sizeof(vis));

67                         sum+=find(t,map[i][j]);

68                     }

69                 }

70                 if(sum>k) ans[len++]=map[i][j];

71             }

72         }

73         if(len==0) printf("-1\n");

74         else

75         {

76             sort(ans,ans+len,cmp);

77             for(i=0;i<len;i++)

78             {

79                 if(i) printf(" ");

80                 printf("%d",ans[i]);

81             }

82             printf("\n");

83         }

84     }

85 }

 set容器

View Code
 1 #include<stdio.h>

 2 #include<string.h>

 3 #include<set>

 4 #include<algorithm>

 5 #include<iostream>

 6 using namespace std;

 7 

 8 const int MAXN=150;

 9 

10 set<int>s;

11 int map[MAXN][MAXN];

12 int pre[MAXN];

13 int vis[MAXN];

14 int used[MAXN];

15 int ans[MAXN];

16 int n,k;

17 

18 int find(int cur,int color)

19 {

20     int i;

21     for(i=1; i<=n; i++)

22     {

23         if(map[cur][i]==color && !vis[i])

24         {

25             vis[i]=1;

26             if(pre[i]==-1 || find(pre[i],color))

27             {

28                 pre[i]=cur;

29                 return 1;

30             }

31         }

32     }

33     return 0;

34 }

35 

36 int main()

37 {

38     int i,j,t,w,sum;

39     int len;

40     while(scanf("%d%d",&n,&k))

41     {

42         s.clear();

43         if(n==0 && k==0) break;

44         memset(map,0,sizeof(map));

45 

46         for(i=1; i<=n; i++)

47         {

48             for(j=1; j<=n; j++)

49             {

50                 scanf("%d",&w);

51                 s.insert(w);

52                 map[i][j]=w;

53             }

54         }

55         len=0;

56         sum=0;

57         set<int>::iterator iter;

58         for(iter=s.begin(); iter!=s.end(); iter++)

59         {

60             //cout<<"值"<<*iter<<endl;

61             memset(pre,-1,sizeof(pre));

62             sum=0;//这里忘记了

63             for(t=1; t<=n; t++)

64             {

65                 memset(vis,0,sizeof(vis));

66                 sum+=find(t,*iter);

67             }

68             if(sum>k) ans[len++]=*iter;

69         }

70         if(len==0) printf("-1\n");

71         else

72         {

73             for(i=0; i<len; i++)

74             {

75                 if(i) printf(" ");

76                 printf("%d",ans[i]);

77             }

78             printf("\n");

79         }

80     }

81 }

 

你可能感兴趣的:(color)