尽管是大水题 但是再怎么说就是自己走过的路啊
不过现在只是二分图入门阶段 到现在为止接触的一些题目真的是太水了 只要 吧题目理解 套个模板就好了 所以这里就只拿一个hdu1498作为水题典例
简单说 题目是个最小点覆盖问题 二分图的最小点覆盖==最大匹配数 问的是哪些数字在k步操作内无法完全覆盖 也就是说最大匹配大于k的有哪些
AC Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
const int maxn=105;
int n,k;
int g[maxn][maxn],link[maxn];
bool vis[maxn];
set<int> kao;
int hungary(int);
bool dfs(int,int);
int main()
{
int temp,ans[maxn];
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==0&&k==0) break;
kao.clear();
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
scanf("%d",&temp);
kao.insert(temp);
g[i][j]=temp;
}
int num=0,kase=0;
for(set<int>::iterator it=kao.begin(); it!=kao.end(); it++)
{
temp=hungary(*it);
if(temp>k) ans[num++]=*it;
}
if(num==0) printf("-1");
else
{
sort(ans,ans+num);
for(int i=0; i<num; i++)
{
if(kase++) putchar(' ');
printf("%d",ans[i]);
}
}
puts("");
}
return 0;
}
int hungary(int key)
{
int num=0;
for(int i=1; i<=n; i++) link[i]=-1;
memset(link,-1,sizeof link);
for(int i=1; i<=n; i++)
{
memset(vis,false,sizeof vis);
if(dfs(i,key)) num++;
}
return num;
}
bool dfs(int x,int key)
{
for(int i=1; i<=n; i++)
if(!vis[i]&&g[x][i]==key)
{
vis[i]=true;
if(link[i]==-1||dfs(link[i],key))
{
link[i]=x;
return true;
}
}
return false;
}