题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1281
题意很难理解...其实就是问最多能放多少个车,然后我们把这个放车的点删去,看会不会影响最大能放车的值,如果能影响,这个点就是一个important点,思路就是我们先将图按行和列分成两个集合求一个二分图最大匹配(裸的匈牙利),然后我们枚举每条边进行删除操作,然后用当前的最大匹配数和之前的最大匹配数比较,不同则就是一个important点。
AC代码:
#include <bits/stdc++.h>
#define maxn 205
using namespace std;
int edge[maxn][maxn];
int pre[maxn];
bool vis[maxn];
int x[maxn], y[maxn];
int n,m,k;
bool dfs(int x){
for(int i=1;i<=m;i++){
if(vis[i] == false && edge[x][i]){
vis[i] = true;
if(pre[i] == -1 || dfs(pre[i])){
pre[i] = x;
return true;
}
}
}
return false;
}
int main()
{
int Case = 1;
while(~scanf("%d%d%d",&n,&m,&k)){
memset(edge,0,sizeof(edge));
for(int i=1;i<=k;i++){
scanf("%d%d",&x[i],&y[i]);
edge[ x[i] ][ y[i] ] = 1;
}
int ans = 0;
int cnt = 0;
memset(pre,-1,sizeof(pre));
for(int i=1;i<=n;i++){
memset(vis,false,sizeof(vis));
if(dfs(i)) ans ++;
}
for(int i=1;i<=k;i++){
edge[ x[i] ][ y[i] ] = 0;
memset(pre,-1,sizeof(pre));
int ans1 = 0;
for(int j=1;j<=n;j++){
memset(vis,false,sizeof(vis));
if(dfs(j)) ans1 ++;
}
if(ans1 != ans) cnt ++;
edge[ x[i] ][ y[i] ] = 1;
}
printf("Board %d have %d important blanks for %d chessmen.\n",Case++,cnt,ans);
}
return 0;
}