匈牙利算法
目前看到最清晰的题解
注:
匈牙利算法仅仅只针对左边的节点枚举,\(mat\) 存的是右边的节点对应左边的节点
\(vis\) 数组代表这一次增广路已经访问过的点,所以每次都要重置 \(vis\) 数组
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,m,e;
vector<int>b[N];
int mat[N];
bool vis[N];
bool find(int x){for(int v:b[x]){if(vis[v]) continue;vis[v]=1;//当前左节点是否被访问过if(!mat[v]||find(mat[v])){//本质上mat仅存的是右节点对应的左节点mat[v]=x;return 1;}}return 0;
}
int hungarian(int tot){int cnt=0;for(int i=1;i<=tot;i++){memset(vis,0,sizeof(vis));if(find(i)) cnt++; }return cnt;
}
int main(){scanf("%d%d%d",&n,&m,&e);for(int i=1;i<=e;i++){int u,v;scanf("%d%d",&u,&v);v+=n;b[u].push_back(v);b[v].push_back(u);}printf("%d\n",hungarian(n));
}