
1 1 1 2 1 1 1 1 2 2 1 1 2 2 2 5 4 1 2 3 4 5 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4 3 3 50 50 50 50 50 50 50 50 50 0 0
-1 1 2 1 2 3 4 5 -1
题意:在校庆活动当中,有n*n个格子,里面放有不同颜色的汽球,让学生去拍汽球,但一次只能拍一行或一列的相同颜色的汽球,并且一个学生最多只能拍k次,问那些颜色的汽球不能在4k次中拍完则输出汽球的颜色,按升序排列,如果没有则输出-1.
解题:看起来无从下手,可是根据题意可知,我们可以把不同颜色的汽球分开来,对每种汽球各求一次,这样就是一个最小顶覆盖问题了。
#include<stdio.h>
#include<string.h>
int map[55][105][105],vist[105],match[105],n;
int find(int i,int c)
{
    for(int j=1;j<=n;j++)
    if(!vist[j]&&map[c][i][j])
    {
        vist[j]=1;
        if(match[j]==0||find(match[j],c))
        {
            match[j]=i; return 1;
        }
    }
    return 0;
}
int main()
{
    int m,c,cc[55];
    while(scanf("%d%d",&n,&m)>0&&n+m!=0)
    {
        memset(map,0,sizeof(map));
        memset(cc,0,sizeof(cc));
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&c); map[c][i][j]=1; cc[c]=1;
        }
        int flag=0,ans;
        for(int c=1;c<=50;c++)
        if(cc[c])
        {
            ans=0; memset(match,0,sizeof(match));
            for(int i=1;i<=n;i++)
            {
                memset(vist,0,sizeof(vist));
                ans+=find(i,c);
            }
            if(ans>m)
            {
               if(flag)printf(" "); printf("%d",c); flag=1;
            }
        }
        if(flag==0)printf("-1");
        printf("\n");
    }
}
hdu149850 years, 50 colors (多个最小顶点覆盖),布布扣,bubuko.com
hdu149850 years, 50 colors (多个最小顶点覆盖)
原文:http://blog.csdn.net/u010372095/article/details/38258053