二分图匹配([洛谷]P3386 模板 二分图匹配)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图匹配([洛谷]P3386 模板 二分图匹配)相关的知识,希望对你有一定的参考价值。
二分图匹配其实十分简单,原理只有一个,能换则换,腾出这个妹子的位置,不要考虑其他人是不是很不满意从他喜欢中最喜欢的那一个变成了他喜欢中的最不喜欢的那一个,知道了这个原理,n遍DFS就可以过了:
#include<stdio.h>
#include<string.h>
const int Inf=1e9+10,maxn=5010,maxm=5010,maxe=10010;
int gi(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9' && ch>='0'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
struct node{
int to,next;
}e[maxe];
int cnt,front[maxn],use[maxn];
int used[maxm],b[maxm],n,m;
void Add(int u,int v){
e[++cnt].to=v;
e[cnt].next=front[u];
front[u]=cnt;
}
bool dfs(int u){//寻找增广路
for(int i=front[u];i;i=e[i].next)
if(!used[e[i].to]){
used[e[i].to]=1;
if(b[e[i].to]==0 || dfs(b[e[i].to])){
use[u]=e[i].to;
b[e[i].to]=u;
return true;
}
}
return false;
}
int ED(){
int ans=0;
for(int i=1;i<=n;i++)
if(!use[i]){
memset(used,0,sizeof(used));
if(dfs(i))ans++;
}
return ans;
}
int main(){
int i,j,k,e;
scanf("%d%d%d",&n,&m,&e);
for(i=1;i<=e;i++){
int u=gi(),v=gi();
if(u<=n && v<=m)Add(u,v);
}
printf("%d\n",ED());
return 0;
}
以上为邻接表版本,如果有需要的,以下是邻接矩阵版本
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int n,m;
int g[1010][1010];
int flag[1010],b[1010];
bool dfs(int u);
int ED();
void init();
int main(){
init();
return 0;
}
void init(){
int i,j,k,e;
scanf("%d%d%d",&n,&m,&e);
for(i=1;i<=e;i++){
int u,v;
scanf("%d%d",&u,&v);
if(u>n || v>m)continue;
g[u][v]=1;
}
printf("%d\n",ED());
}
int ED(){
int ans=0;
for(int i=1;i<=n;i++){
memset(flag,0,sizeof(flag));
if(dfs(i))ans++;
}
return ans;
}
bool dfs(int u){
for(int v=1;v<=m;v++)
if(g[u][v] && !flag[v]){
flag[v]=1;
if(!b[v] || dfs(b[v])){
b[v]=u;
return true;
}
}
return false;
}
以上是关于二分图匹配([洛谷]P3386 模板 二分图匹配)的主要内容,如果未能解决你的问题,请参考以下文章