hdu1054 匈牙利算法(增广路) (附匈牙利算法模板)
来源:互联网 发布:软件三层结构 编辑:程序博客网 时间:2024/05/18 18:55
嗯。。。。今天开始写博客。。。。大一过去一半了。。。希望下半年能有个好的开始吧
先贴上百度百科里面对匈牙利算法的描述
算法轮廓:
⑴置M(这里M是图的一个子边集, 也就是现在要求的最大匹配的边集)为空
⑵找出一条增广路径P,通过异或操作获得更大的匹配M’代替M
⑶重复⑵操作直到找不出增广路径为止
而在代码的实现中,我们考虑枚举二分图左边点集中的点x的所有出边指向的点y,若y之前没有被匹配,那么(x,y)就是一对可以的匹配,我们便
将匹配数+1,。否则,我们便考虑给算法中已经于y匹配的点x'另找一个匹配,如果这时我们给x'找到了另外的匹配,那么(x,y)便可以成为一对行
的匹配。给x'寻找匹配的过程我们可以用dfs解决。从而我们有了解决最大匹配的方法。
下面给出我的模板
vector<int> v[]; //储存边的邻接表int pre[]; // pre[i]记录与i匹配的左边点集中的点bool flag[]; //记录是否访问过某一个点bool find(int x) { int len = v[x].size(); rep(i, 0, len) { if(!flag[v[x][i]]) { flag[v[x][i]] = true; if(pre[v[x][i]] == -1 || find(pre[v[x][i]])) { pre[v[x][i]] = x; return true; } } } return false;}int hungary(int n) { int ans = 0; memset(pre, 255, sizeof(pre)); rep(i, 0, n) { memset(flag, 0, sizeof(flag)); if(find(i)) ans++; } return ans;//ans即为所求的最大匹配}然后以hdu的1054作为例题
题目传送门http://acm.hdu.edu.cn/showproblem.php?pid=1054
(另一道poj上的二分匹配,不过加了二分枚举答案一步,链接点这儿)
完全就是简单的匹配,不过建的是无向图而已
由于模板是在这道题做出之后才有的。。。所以模板的形式和题目AC的代码略有不同。。。
#include <iostream>#include <cstdio>#include <vector>using namespace std;#define MAX_N 1505int pre[MAX_N];bool flag[MAX_N];vector<int> map[MAX_N];int n;int find(int cur){int k;vector<int>::iterator iter, end = map[cur].end();for (iter = map[cur].begin(); iter < end; iter++){k = *iter;if (!flag[k]){flag[k] = true;if (pre[k] == -1 || find(pre[k])){pre[k] = cur;return 1;}}}return 0;}int main(){int i, j, r, k, num, sum;while (scanf("%d", &n) != EOF){memset(pre, -1, sizeof(pre));for (i = 0; i < n; i++) map[i].clear();for (i = 0; i < n; i++){scanf("%d:(%d)", &k, &num);for (j = 0; j < num; j++){scanf("%d", &r);map[k].push_back(r);map[r].push_back(k);}}sum = 0;for (i = 0; i < n; i++){memset(flag, false, sizeof(flag));sum += find(i);}printf("%d\n", sum / 2);}return 0;}
当然这个问题里面还涉及到了最小点覆盖和最大匹配的关系,明显图中所有的点都可以在最大匹配的边集中找到包含这个点的边,所以只要从每个边上
各选一个点的话,这时这些点肯定满足覆盖。而如果减少一个点的话,这些点就相当于从一个不完全匹配的边集中找到的点,这时肯定有边集没有涉及
到的点,所以可以保证这时的答案是最小的符合条件的。而至于答案中是sum/2,是因为无向图的话,这个算法对同一条边会求两次,所以会除以2
0 0
- hdu1054 匈牙利算法(增广路) (附匈牙利算法模板)
- 匈牙利算法(DFS增广)
- 二分图最大匹配(匈牙利算法-DFS增广模板)
- 匈牙利算法与增广路径
- hdu1054匈牙利算法/最小覆盖点
- poj1469匈牙利算法(模板)
- 【二分匹配】【匈牙利算法即由增广路求最大匹配模板】
- 匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 【匈牙利算法模板】
- 匈牙利算法模板
- 模板:匈牙利算法
- 匈牙利算法模板
- 匈牙利算法模板
- 匈牙利算法模板
- 【图论】匈牙利算法模板
- 匈牙利算法模板
- Python学习系列十:异常处理
- Android解析xml
- C 输入、输出库函数学习总结(printf & scanf, gets & puts, fgets & fputs, getchar & putchar)
- 存储过程
- 我想要的不是“我爱你”,而是“我愿意“,因为,我想给你一辈子的承诺。
- hdu1054 匈牙利算法(增广路) (附匈牙利算法模板)
- java数组选择排序
- Linux软连接和硬链接
- 关于搜索的优化
- ava JVM虚拟机选项 Xms Xmx PermSize MaxPermSize 区别
- java冒泡排序
- 调用系统自带的发短信Activity
- java数组(折半查找)
- java进制之间转换