二分图最大匹配 Hopcroft-Karp算法模板
2015-09-08 15:26
405 查看
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; const int MAXN = 3010;//左边节点数量、右边节点数量 const int MAXM = 3010*3010;//边的数量 const int INF = 0x7FFFFFFF; struct Edge { int v; int next; }edge[MAXM]; int nx, ny; int cnt;int dis; int first[MAXN]; int xlink[MAXN], ylink[MAXN]; /*xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。*/ int dx[MAXN], dy[MAXN]; /*dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号*/ int vis[MAXN]; //寻找增广路的标记数组 void init() { cnt = 0; memset(first, -1, sizeof(first)); memset(xlink, -1, sizeof(xlink)); memset(ylink, -1, sizeof(ylink)); } void read_graph(int u, int v) { edge[cnt].v = v; edge[cnt].next = first[u], first[u] = cnt++; } int bfs() { queue<int> q; dis = INF; memset(dx, -1, sizeof(dx)); memset(dy, -1, sizeof(dy)); for(int i = 0; i < nx; i++) { if(xlink[i] == -1) { q.push(i); dx[i] = 0; } } while(!q.empty()) { int u = q.front(); q.pop(); if(dx[u] > dis) break; for(int e = first[u]; e != -1; e = edge[e].next) { int v = edge[e].v; if(dy[v] == -1) { dy[v] = dx[u] + 1; if(ylink[v] == -1) dis = dy[v]; else { dx[ylink[v]] = dy[v]+1; q.push(ylink[v]); } } } } return dis != INF; } int find(int u) { for(int e = first[u]; e != -1; e = edge[e].next) { int v = edge[e].v; if(!vis[v] && dy[v] == dx[u]+1) { vis[v] = 1; if(ylink[v] != -1 && dy[v] == dis) continue; if(ylink[v] == -1 || find(ylink[v])) { xlink[u] = v, ylink[v] = u; return 1; } } } return 0; } int MaxMatch() { int ans = 0; while(bfs()) { memset(vis, 0, sizeof(vis)); for(int i = 0; i < nx; i++) if(xlink[i] == -1) { ans += find(i); } } return ans; } int main() { init(); nx=0,ny=0;//左边顶点数量,右边顶点数量 //加边的格式,左边的i和右边的j相连 read_graph(i, j); int ans = MaxMatch(); printf("%d\n\n", ans); return 0; }
相关文章推荐
- Linux运维汇总笔记
- Hadoop安装配置
- Linux Top 命令解析 比较详细
- 关于linux文件下库的链接问题 openssl pcre
- 把linux的man手册转化为windows下可读的格式
- 25-linux中的任务调度命令
- 树莓派2B安装OpenCV 2.4.11
- Linux说明书 - man浅谈
- 查询linux 下文件夹多少个文件
- openssl - 怎么打开POD格式的帮助文件
- Centos opencv3.0 ffmpeg 的兼容性
- Nginx技术手册
- openssl - X509证书操作函数
- Linux文件系统管理
- Linux NTP配置详解 (Network Time Protocol)
- 9月5日 linux任务计划作业
- Linux日志系统学习!!!
- linux服务器报警之利用Java邮件报警
- Linux Virtual Server负载均衡 ipvsadm使用方法
- 临时解决Apache服务器假死的参数配置