匈牙利算法和hopcroft_karp算法模板
来源:互联网 发布:winsteel软件下载 编辑:程序博客网 时间:2024/06/06 04:17
今晚学习了hopcroft_karp算法,留个模板,顺便也留个匈牙利算法模板。
题目为POJ 1469,在本题中,两种算法所用时间基本一致
//hopcroft_karp算法,复杂度O(sqrt(n)*m)#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <queue>using namespace std;const int N = 320;const int INF = 0x3f3f3f3f;struct edge{ int to, next;}g[N*N];int match[N], head[N];bool used[N];int p, n;int nx, ny, cnt, dis; //nx,ny分别是左点集和右点集的点数int dx[N], dy[N], cx[N], cy[N]; //dx,dy分别维护左点集和右点集的标号//cx表示左点集中的点匹配的右点集中的点,cy正好相反void add_edge(int v, int u){ g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;}bool bfs() //寻找增广路径集,每次只寻找当前最短的增广路{ queue<int> que; dis = INF; memset(dx, -1, sizeof dx); memset(dy, -1, sizeof dy); for(int i = 1; i <= nx; i++) if(cx[i] == -1) //将未遍历的节点入队,并初始化次节点距离为0 que.push(i), dx[i] = 0; while(! que.empty()) { int v = que.front(); que.pop(); if(dx[v] > dis) break; for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(dy[u] == -1) { dy[u] = dx[v] + 1; if(cy[u] == -1) dis = dy[u]; //找到了一条增广路,dis为增广路终点的标号 else dx[cy[u]] = dy[u] + 1, que.push(cy[u]); } } } return dis != INF;}int dfs(int v){ for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(! used[u] && dy[u] == dx[v] + 1) //如果该点没有被遍历过并且距离为上一节点+1 { used[u] = true; if(cy[u] != -1 && dy[u] == dis) continue; //u已被匹配且已到所有存在的增广路终点的标号,再递归寻找也必无增广路,直接跳过 if(cy[u] == -1 || dfs(cy[u])) { cy[u] = v, cx[v] = u; return 1; } } } return 0;}int hopcroft_karp(){ int res = 0; memset(cx, -1, sizeof cx); memset(cy, -1, sizeof cy); while(bfs()) { memset(used, 0, sizeof used); for(int i = 1; i <= nx; i++) if(cx[i] == -1) res += dfs(i); } return res;}int main(){ int t, a, b; scanf("%d", &t); while(t--) { cnt = 0; memset(head, -1, sizeof head); scanf("%d%d", &p, &n); for(int i = 1; i <= p; i++) { scanf("%d", &a); for(int j = 0; j < a; j++) { scanf("%d", &b); add_edge(i, b); } } nx = p, ny = n; if(hopcroft_karp() == p) printf("YES\n"); else printf("NO\n"); } return 0;}
//匈牙利算法,复杂度O(nm)#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <vector>using namespace std;const int N = 320;struct edge{ int to, next;}g[N*N];int match[N], head[N];bool use[N];int p, n;int nx, ny, cnt;void add_edge(int v, int u){ g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;}bool dfs(int v){ for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(use[u] == false) { use[u] = true; if(match[u] == -1 || dfs(match[u])) { match[u] = v; return true; } } } return false;}int hungary(){ int res = 0; memset(match, -1, sizeof match); for(int i = 1; i <= nx; i++) { memset(use, 0, sizeof use); if(dfs(i)) res++; } return res;}int main(){ int t, a, b; scanf("%d", &t); while(t--) { cnt = 0; memset(head, -1, sizeof head); scanf("%d%d", &p, &n); for(int i = 1; i <= p; i++) { scanf("%d", &a); for(int j = 0; j < a; j++) { scanf("%d", &b); add_edge(i, b); } } nx = p, ny = n; if(hungary() == p) printf("YES\n"); else printf("NO\n"); } return 0;}
0 0
- 匈牙利算法和hopcroft_karp算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 【匈牙利算法模板】
- 匈牙利算法模板
- 模板:匈牙利算法
- 匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 【图论】匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法&模板
- 匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 【笔记+模板】 匈牙利算法
- asp.net课程设计——物流信息供求网
- 第九周项目二我的数组类
- JavaScript入门
- glclear glclearcolor小记
- Android-仿微信菜单
- 匈牙利算法和hopcroft_karp算法模板
- HttpURLConnection
- Android初级教程之内容提供者获取联系人信息
- 重识char与vchar
- 将uniy3D集成到android的子窗口中
- ARM 开发板insmod安装内核模块时,Unknown symbol usb_register_driver (err 0)
- 数据库6 关系代数(relational algebra) 函数依赖(functional dependency)
- 7、AngularJs的压缩问题
- request获取各种路径总结