二分图最大匹配模板【匈牙利;Dinic最大流】
二分图最大匹配模板【匈牙利;Dinic最大流】
匈牙利算法
int n,m; vector<int> map[100010]; int match[100010];//保存匹配的互相点 bool vis[100010]; bool dfs(int u) { for(int j=0;j<map[u].size();j++) { int v=map[u][j]; if(!vis[v]) { vis[v]=true; if(!match[v]||dfs(match[v])) { match[v]=u; return true; } } } return false; } int solve() { int ans=0; for(int i=1;i<=n;i++) { memset(vis,false,sizeof(vis)); if(dfs(i)) ans++; } return ans; }
十分简洁好理解的版,就是不断找增广路
Dinic最大流
最大流的版本重点在于建图
建图后可套入任何一个最大流模板
求出的最大流即为最大匹配
不会最大流的小伙伴可以看我的博客
图论算法-网络最大流【EK;Dinic】
建边过程:
int n,m,e; //n,m分别为两个点集点数;e为原图中的边 cin>>n>>m>>e; for(int i=1;i<=e;i++) { int u,v; cin>>u>>v; add(u,v+n,1);//先建原图的边,要注意节点编号以题目为准 add(v+n,u,0); } int s=0,t=n+m+1;//建立超级源点和超级汇点 for(int i=1;i<=n;i++) { add(0,i,1); add(i,0,0);//将超级源点对X点集每个点引一条容量为1的边 } for(int i=n+1;i<=n+m;i++) { add(i,t,1);将Y点集每个点向超级汇点引一条容量为1的边 add(t,i,0); }