匈牙利算法 && EK(邻接表)
2015-09-05 09:53
344 查看
/** 用邻接表添边是图论中基础中的基础,实用价值十分可观 添边为固定格式,理解的最好办法是画几个点,自己用手 模拟一下添边的过程,你会感慨万千,成就感不言而喻。。 链接表 3剑客为:edge[], edgeHead[], ne; edge[] 为每条边得结构体,你可以在里面放任何附加东西 如:边权w, 流量c, 费用cost。 但v, next是最基本得两个 变量,这决定了链接表的正常工作。。edge[u].v 即表示边 u-v edge[u].next 为u 连接的下条边在edge[]中的下标 edgeHead[u] 表示节点u 在edge[] 中的位置,通过edgeHead[u]和 edge[u].next 即可遍历连接u 的所有边,具体操作见下代码。 特级注意:edgeHead[] 和 ne 的初始化 */ /** 匈牙利 */ #include <cstring> struct { int v, next; }edge[EMax]; int edgeHead[NMax], link[NMax], vis[NMax]; int ne, n; //初始化为1 //n 为匹配点的个数 //初始化edgeHead[]数组为0 void addEdge(int u, int v) { edge[ne].v = v; edge[ne].next = edgeHead[u]; edgeHead[u] = ne++; } bool dfs(int u) { for (int i=edgeHead[u]; i; i=edge[i].next) { int v = edge[i].v; if (!vis[v]) { vis[v] = true; if (link[v]==-1 || dfs(link[v])) { link[v] = u; return true; } } } return false; } int hungary() { int ans = 0; memset(link, -1, sizeof (link)); for (int i=1; i<=n; i++) { memset(vis, 0, sizeof (vis)); if (dfs(i)) ans++; } return ans; } /** EK */ #include <algorithm> #include <cstdio> #include <csting> const int inf = 0x3f3f3f3f; struct { int u, v, c, next; }edge[EMax]; int ne, edgeHead[NMax], pre[NMax]; int ans; //ne 要初始化为2 因为下面找逆向边所需 //2^1 = 3 3^1 = 2 //即偶数的逆向边即为加1,奇数的逆向边减1 //没关系,即使不理解也没事,只要你相信,当你理解后你会豁然开朗你会觉得它是如此简单就好 void addEdge(int u, int v, int c) { edge[ne].u = u; edge[ne].v = v; edge[ne].c = c; edge[ne].next = edgeHead[u]; edgeHead[u] = ne++; edge[ne].u = v; edge[ne].v = u; edge[ne].c = 0; edge[ne].next = edgeHead[v]; edgeHead[v] = ne++; } bool bfs(int s, int t) { int que[NMax], vis[NMax], head=0, tail=1; memset(vis, 0, sizeof (vis)); que[0] = s; vis[s] = true; while (tail > head) { int u = que[head++]; for (int i=edgeHead[u]; i; i=edge[i].next) { int v = edge[i].v; if (!vis[v] && edge[i].c) { pre[v] = i; if (v == t) return true; que[tail++] = v; vis[v] = true; } } } return false; } void end(int s, int t) { int i, u, sum=inf; for (u=t; u!=s; u=edge[i].u) { i = pre[u]; sum = min(sum, edge[i].c); } for (u=t; u!=s; u=edge[u].u) { i = pre[u]; edge[i].c -= sum; edge[i^1].c += sum; } ans += sum; } void EK(int s, int t) { while (bfs(s, t)) end(s, t); } //初始化edgeHead = 0, ne = 2; 收藏于 2011-11-23 来自于百度空间
相关文章推荐
- 前端路上的各种问题-javascript—7
- bzoj3990[SDOI2015]排序
- WHERE CAN I BUY DAKELE BIG COLA 3 ?
- Windows内存管理
- Leetcode: Decode Ways
- dhcpd 软件,出现客户端获取ip时间长的问题
- 一款极具工匠情怀的...
- js怎么跳转页面?
- leetcode_Unique Binary Search Trees_easy
- java操纵redis工具类(切片链接池方式)
- Wordpress安装
- 指针
- 一个人的网站开发
- 微笑和挑战,不断进步
- 字符串和字符数组的区别以及sizeof和strlen的区别
- 匈牙利算法(二分图匹配)
- C#中方法参数传递机制
- costFunctionReg
- codeforces 101A HOME 排序
- 【UI初级 连载四】--------UI常用控件