这道题目,还是需要仔细读读的,,,如果你不仔细读的时候说不定就用错方法了,,,
在此,想善意的提醒下各位ACMer,一定要看清题目,,
而这道题目,选择二分分配的原因也就是因为,一次他只能选择一行或者一列,而扫描一行或者一列,需要的次数,就正好是最大匹配数目,,,,我一定悉心研究清楚,,回头专门弄个这个讲解为什么的博文发出来.
而这道题目,个人觉得,新颖度还是比较高的,,,涉及到很多方面的知识,
现在贴出代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int N,K;//N stands for the lenth of rows or columns,and the M represents the number of times;
int visit[105];
int map[105][105];
int link[105];
int count[55];
int a[55];
int find(int x,int color)
{
for(int i=1;i<=N;i++)
{
if(map[x][i]==color&&!visit[i])
{
visit[i]=1;
if(!link[i]||find(link[i],color))
{
link[i]=x;
return 1;
}
}
}
return 0;
}
int getnum(int color)
{
int sum=0;
memset(link,0,sizeof(link));
for(int i=1;i<=N;i++)
{
memset(visit,0,sizeof(visit));
if(find(i,color))
sum++;
}
// printf("%d*******%d",color,sum);
return sum;
}
int main()//悲哀,,,看了好几次,才发现让求的是不可能打破的气球的种类,想死...- -#
{
while(scanf("%d%d",&N,&K),N|K)
{
memset(count,0,sizeof(count));
memset(map,0,sizeof(map));
memset(a,0,sizeof(a));
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
scanf("%d",&map[i][j]);
count[map[i][j]]++;
}
}
int kk=0;
for(i=1;i<=50;i++)
{
if(count[i]&&getnum(i)>K)
{
a[kk++]=i;
// printf("%d__\n",a[kk]);
}
}
if(kk==0)
printf("-1\n");
else
{
for(i=0;i<kk;i++)
{
printf(i==0?"%d":" %d",a[i]);
}
printf("\n");
}
}
return 0;
}