hdu 1498 (最小顶点覆盖)

每次只能消除一行或一列的相同颜色的气球,

求有多少种气球在k次内不能消除

求出每种气球最少需要多少次消除,就跟hdu 2119消除1用多少次是一样

将行和列分别看成二分图的两个集合,每个气球都是一条边,用最少的点覆盖所有相同颜色的边,最小顶点覆盖



#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int map[101][101],link[101],color[55],mark[101],n,c[55];
int cmp(const void *a,const void *b)
{
    return *(int *)a-*(int *)b;
}
int find(int i,int colo)
{
    int j;
    for(j=1;j<=n;j++)
    {
        if(map[i][j]==colo&&mark[j]==0)
        {
            mark[j]=1;
            if(link[j]==0||find(link[j],colo)==1)
            {
                link[j]=i;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int i,j,sum,k,temp,num;
    while(scanf("%d%d",&n,&k),n&&k)
    {
        temp=0;
        memset(map,0,sizeof(map));
        memset(color,0,sizeof(color));
        memset(mark,0,sizeof(mark));
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                scanf("%d",&map[i][j]);
                if(mark[map[i][j]]==0)
                {
                    color[temp++]=map[i][j];
                    mark[map[i][j]]=1;
                }
            }
            num=0; 
            for(i=0;i<temp;i++)
            {
                memset(link,0,sizeof(link));
                sum=0;
                for(j=1;j<=n;j++)
                {
                    memset(mark,0,sizeof(mark));
                    sum=sum+find(j,color[i]);
                }
                if(sum>k)
                {
                    c[num++]=color[i];
                }
            }
            qsort(c,num,sizeof(c[0]),cmp);
            if(num==0)
                printf("-1\n");
            else
            {
                printf("%d",c[0]);
                for(i=1;i<num;i++)
                    printf(" %d",c[i]);
                printf("\n");
            }
    }
    return 0;
}


你可能感兴趣的:(编程,算法,百度,ACM,二分匹配)