标签:二分匹配

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