题目大意
给你一个n*n的矩阵,在矩阵中分布着s种颜色的气球,给你k次扎破气球的操作,每次的操作可以扎破一行或一列的同一种颜色的气球。问:在k次的操作后有几种颜色的气球是不能被完全扎破的。
解题思路
对每种颜色的气球求最小覆盖点 >k就就是答案了
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<cstdio>
using namespace std;
const int maxn=550;
map<int,int>mmp;
int cnt;
int ans[maxn];
int mp[maxn][maxn],mat[maxn];
int mx[maxn],my[maxn],e[maxn][maxn],n;
int v[maxn];//标记数组(查找过程中曾试图改变过妹子的归属问题,但是没有成功
int path(int i)
{
int j;
for(j=0;j<n;j++)
{
if(e[i][j]&&!v[j])//如果有暧昧并且没有标记过
{
v[j]=1;
if(my[j]==-1||path(my[j]))//名花有主或者可以腾位置
{
my[j]=i;
mx[i]=j;
return 1;
}
}
}
return 0;
}
int hungry()
{
int res=0;
int i;
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));
for(i=0;i<n;i++)
{
if(mx[i]==-1)
{
memset(v,0,sizeof(v));
res+=path(i);
}
}
return res;
}
int main()
{
int k,i,j,m,p,x;
while(cin>>n>>k)
{
if(n==0||k==0)
break;
cnt=1;
mmp.clear();
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cin>>mp[i][j];
if(mmp[mp[i][j]])
continue;
else
{
mmp[mp[i][j]]=cnt;
mat[cnt]=mp[i][j];
cnt++;
}
}
}
m=0;
for(p=1;p<cnt;p++)
{
x=mat[p];
memset(e,0,sizeof(e));
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(mp[i][j]==x)
e[i][j]=1;
}
}
if(hungry()>k)
{
ans[m]=x;
m++;
}
}
if(m==0)
cout<<"-1"<<endl;
else
{
sort(ans,ans+m);
cout<<ans[0];
for(i=1;i<m;i++)
cout<<" "<<ans[i];
cout<<endl;
}
}
return 0;
}