题意:
给你一个n*n的矩阵,在矩阵中分布着s种颜色的气球,给你k次扎破气球
的操作,每次操作可以扎破一行,或一列的同一颜色的气球。问在k次操
作后有那几种颜色的气球是不能被完全扎破的.
解题:
利用二分图匹配,寻找每一种颜色对应的最大匹配(行和列分别为X集合,Y集合;map[i,j]代表一个搭配),
如果大于k则输出"-1",否则输出颜色的递增序列
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 100010
#define MOD 1000000007
int n,m,match[110];
int mp[110][110],vis[110];
int Find(int u,int c)
{
for(int v = 0; v < n; v++)
if(mp[u][v] == c && !vis[v])
{
vis[v] = 1;
if(match[v] == -1 || Find(match[v],c))
{
match[v] = u;
return 1;
}
}
return 0;
}
int main()
{
int t,C = 1;
while(scanf("%d%d",&n,&m) && (n+m))
{
memset(mp,0,sizeof(mp));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d",&mp[i][j]);
int ans[110],t = 0;
for(int i = 1; i <= 50; i++)
{
int cnt = 0;
memset(match,-1,sizeof(match));
for(int j = 0; j < n; j++)
{
memset(vis,0,sizeof(vis));
cnt += Find(j,i);
}
if(cnt > m)
ans[t++] = i;
}
if(!t)
printf("-1");
else
for(int i = 0; i < t; i++)
printf(i == 0?"%d":" %d",ans[i]);
printf("\n");
}
return 0;
}