在n*n的矩阵里面有1到50这样标记的气球,每次你可以搓爆同行或列的同标记的气球,问k次机会不能戳爆的气球的编号
PS:这题跟上一题的划掉1一个道理,同种气球就是1,只不过现在是对每一个气球都单独当成01矩阵来最小点覆盖,最后统计不能在k内覆盖的
#include<iostream>
#include<cstdio>
#include<cstring>
const int maxn = 105;
using namespace std;
int n,m;
int map[maxn][maxn];
int link[maxn],vis[maxn];
int cnt[maxn];
//以某种颜色出发,进行的点覆盖
int Find(int x, int col)
{
for(int i = 1; i <= n; i++)
{
if(map[x][i] ==col&&!vis[i])
{
vis[i] = 1;
if(link[i] == 0 || Find(link[i],col))
{
link[i] = x;
return 1;
}
}
}
return 0;
}
int Math(int col)
{
memset(link, 0, sizeof(link));
int ret = 0;
for(int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
ret += Find(i,col);
}
return ret;
}
int main()
{
while(scanf("%d%d",&n,&m) != EOF)
{
if(n == 0 && m == 0)break;
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d",&map[i][j]);
cnt[map[i][j]]++;
}
}
int num[maxn], t = 0;
for(int i = 1; i <= 50;i++)
{
if(cnt[i] && Math(i) > m)
{
num[t] = i;
t++;
}
}
if(t == 0)
{
printf("%d\n",-1);
}
else
{
printf("%d",num[0]);
for(int i = 1; i < t; i++)
printf(" %d",num[i]);
printf("\n");
}
}
return 0;
}