您的位置:首页 > 其它

hdu 1498 50 years, 50 colors (二分匹配)

2012-08-02 15:11 295 查看

点击打开链接

题意:
给你一个n*n的矩阵,在矩阵中分布着s种颜色的气球,给你k次扎破气球
的操作,每次操作可以扎破一行,或一列的同一颜色的气球。问在k次操
作后有那几种颜色的气球是不能被完全扎破的.
解题:
利用二分图匹配,寻找每一种颜色对应的最大匹配(行和列分别为A集合,B集合;M[i,j]代表一个搭配),
如果大于k则输出"-1",否则输出颜色的递增序列
注:在二分图中求最少的点,让每条边都至少和其中的一个点关联,这就是
二分图的“最小顶点覆盖”。
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
intmap[101][101],mark[101];
intv[101],link[101];
inta[101],color[101];
intk,n;
intcmp(constvoid*a,constvoid*b)
{
return*(int*)a-*(int*)b;
}
intdfs(inti,intk)
{
intj;
for(j=1;j<=n;j++)
{
if(map[i][j]==k&&!v[j])
{
v[j]=1;
if(link[j]==0||dfs(link[j],k))
{
link[j]=i;
return1;
}
}
}
return0;
}
intmain()
{
inti,j,t,tt,ans;
while(scanf("%d%d",&n,&k)!=-1)
{
if(n==0&&k==0)
break;
memset(color,0,sizeof(color));
memset(mark,0,sizeof(mark));
t=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
if(!mark[map[i][j]])
{
mark[map[i][j]]=1;
color[t++]=map[i][j];
}
}
}
tt=0;
for(i=0;i<t;i++)
{
ans=0;
memset(link,0,sizeof(link));
for(j=1;j<=n;j++)
{
memset(v,0,sizeof(v));
if(dfs(j,color[i]))
ans++;
}
if(ans>k)
a[tt++]=color[i];
}
if(tt==0)
printf("-1\n");
else
{
qsort(a,tt,sizeof(a[0]),cmp);
for(i=0;i<tt-1;i++)
printf("%d",a[i]);
printf("%d\n",a[i]);
}
}
return0;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: