题目大意;对n*n的气球执行k次操作,每次操作可以击破一排或一列气球,输出k次操作后未能完全击破的气球编号,注意按循序输出。如果没有则输出-1。
解题思路:用二分匹配求出每种气球的最大匹配Mi,如果Mi大于k,则输出气球编号,如果没有Mi大于k,则输出-1;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int map[101][101],dis[101],flag[101],balloons[101],f[101];
int n,m,k;
int dfs(int t,int p)//二分匹配 p为气球编号
{
for(int i=1; i<=n; i++)
{
if(!flag[i]&&map[t][i]==p)//模式与一般的二分匹配差不多,把map[][]=1,改成=p;
{
flag[i]=1;
if(dis[i]==-1||dfs(dis[i],p))
{
dis[i]=t;
return 1;
}
}
}
return 0;
}
int maxn(int p)
{
int sum=0;
memset(dis,-1,sizeof(dis));
for(int i=1; i<=n; i++)
{
memset(flag,0,sizeof(flag));
if(dfs(i,p))
sum++;
}
return sum;
}
int main()
{
int i,j,mark,flags;
while(cin>>n>>m)
{
if(n==0&&m==0)break;
memset(balloons,0,sizeof(balloons));//初始化为0,记录气球编号
k=0;
mark=0;flags=0;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
cin>>map[i][j];
if(balloons[map[i][j]]==0)//如果气球未出现过,则做记录
{
balloons[map[i][j]]=1;
f[k++]=map[i][j];//把气球编号存入数组f中
}
}
sort(f,f+k);//对号码排序
for( j=0; j<k; j++)
{
if(maxn(f[j])>m)
{
if(flags)//注意输出格式,最后一个不要空格
cout<<" ";
cout<<f[j];
flags=1;
mark=1;//如果有没能完全击破的气球,则不用输出-1
}
}
if(!mark)cout<<"-1";//没有选择,则输出-1
cout<<endl;
}
}