先寻找二分图最大匹配
然后根据最大匹配来判断匹配中的每个点是否是重要点(即删掉这个点匹配数是否变少)
暴力循环判断一遍即可
#include<iostream>
#include<cstdio>
#include<string.h>
#include<vector>
using namespace std;
const int maxn = 105;
int used[maxn];
int linker[maxn];
vector<int>v[maxn];
int mp[105][105];
int n,m,k;
void init(){
memset(mp,0,sizeof(mp));
}
bool dfs(int u){
for(int i =1;i<=m;++i){
int to = i;
if(!used[to]&&mp[u][to]){
used[to]=1;
if(linker[to]==-1||dfs(linker[to])){
linker[to] = u;
return true;
}
}
}
return false;
}
int hungry(){
memset(linker,-1,sizeof(linker));
int res = 0;
for(int i =1;i<=n;++i){
memset(used,0,sizeof(used));
if(dfs(i))
res++;
}
return res;
}
int main(){
int ca = 1;
while(~scanf("%d%d%d",&n,&m,&k)){
int x,y;
init();
for(int i =0;i<k;++i){
scanf("%d%d",&x,&y);
mp[x][y]=1;
}
int maxs = hungry();
int sum = 0;
int sum1 = 0;//improtant
int lin[200];
for(int i =1;i<=m;++i){
lin[i] = linker[i];
}
for(int i=1;i<=m;++i){
if(lin[i]!=-1){
sum++;
int from = lin[i];
mp[from][i]=0;
int temp = hungry();
mp[from][i]=1;
if(temp!=maxs)
sum1++;
}
}
printf("Board %d have %d important blanks for %d chessmen.\n",ca++,sum1,sum);
}
}