今天学了一下二分图匹配,开始写这个题目。
刚开始感觉根本不用二分图匹配就可以做啊……emmm
然后开始想怎么建图,感觉怎么建图都很麻烦,最后yy了一个不算建图的写法,直接在map里找,然后横坐标和纵坐标算成二分图的两边?
写代码真实有趣!
有时候思维就是被模板僵化的鸭
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define N 105
#define ll long long
using namespace std;
int n,m,k;
bool in[N];
int match[N];
int mp[N][N]; //图
struct node{
int x,y;
}p[N];
bool fp(int u){
go(i,1,m){
if (mp[u][i]==0) continue;
if (!in[i]){
in[i]=true;
if (match[i]==-1||fp(match[i])){
match[i]=u;
return true;
}
}
}
return false;
}
int maxp(){
int ans=0;
go(i,1,n){
memset(in,false,sizeof(in));
if (fp(i)) ans++;
}
return ans;
}
int main(){
int x,y,inv,inv2,ans,ca=0;
while (scanf("%d%d%d",&n,&m,&k)!=EOF){
memset(mp,0,sizeof(mp));
go(i,1,k){
scanf("%d%d",&x,&y);
mp[x][y]=1;
}
memset(match,-1,sizeof(match));
inv=maxp();
//printf("%d\n",inv);
int k=0;
go(i,1,m){
if (match[i]!=-1){
p[++k]=(node){match[i],i};
}
}
ans=0;
go(i,1,k){
mp[p[i].x][p[i].y]=0;
memset(match,-1,sizeof(match));
inv2=maxp();
if (inv2<inv) ans++;
mp[p[i].x][p[i].y]=1;
}
printf("Board %d have %d important blanks for %d chessmen.\n",++ca,ans,inv);
}
}
二分图匹配