匈牙利算法 (poj1422-Air Raid,poj1469-COURSES)
2009-07-13 08:55
477 查看
首先注意区分“最小路径覆盖”(minimum path cover)和“最小边覆盖”(minimum edge cover)以及“最小点覆盖”(minimum vertex cover)之间的区别。详细资料可以查询Wiki。
最小路径覆盖可以转化为二分图的最大匹配(maximum bipartite matching) 。公式为最小路径覆盖数=原图节点数-二分图最大匹配数。
求最大匹配的方法有两种:一是将二分图增添两个节点(source起点和sink终点)构造一个流网络(flow network),然后就可以按求最大流的算法来计算,基本的算法有Ford-Fulkerson算法。不过这样实现起来比较麻烦,下面着重介绍第二种方法:匈牙利算法(Hungarian algorithm )。
匈牙利算法其实和基于增广路径(augmenting path)的最大流算法是比较相似的。不同点在于:
一,匈牙利算法不需要构造流网络,也就是说不需要增添节点,并且二分图是无向图,不需要转换为流网络中的有向图。
二,匈牙利算法的增广路径(设为P)有附加条件:P的第一条边必须是尚未匹配的边,第二条边是已经匹配的边,如此未匹配和已匹配的边交替出现,最后一条边仍然是未匹配边(注意P可以是只有一条未匹配边的路径)。根据增广路径的附加条件可以看出一个特点:P的未匹配边一定比已匹配边多一条。
三,匈牙利算法依次对二分图的半边(左半边或者右半边,条件是节点数少的一边)的每个节点开始找增广路径,如果找到则取反:未匹配的边变成匹配边,已匹配边去掉匹配关系。这样的结果是路径P的匹配边数量增加一条,未匹配边数量减少一条。寻找增广路径的方法为DFS或者BFS递归。
四,当二分图中不存在增广路径时即产生最大匹配数。
匈牙利算法的实质就是找增广路径,并对增广路径做取反操作,直到没有增广路径为止。
匈牙利算法的基本流程:
最小路径覆盖可以转化为二分图的最大匹配(maximum bipartite matching) 。公式为最小路径覆盖数=原图节点数-二分图最大匹配数。
求最大匹配的方法有两种:一是将二分图增添两个节点(source起点和sink终点)构造一个流网络(flow network),然后就可以按求最大流的算法来计算,基本的算法有Ford-Fulkerson算法。不过这样实现起来比较麻烦,下面着重介绍第二种方法:匈牙利算法(Hungarian algorithm )。
匈牙利算法其实和基于增广路径(augmenting path)的最大流算法是比较相似的。不同点在于:
一,匈牙利算法不需要构造流网络,也就是说不需要增添节点,并且二分图是无向图,不需要转换为流网络中的有向图。
二,匈牙利算法的增广路径(设为P)有附加条件:P的第一条边必须是尚未匹配的边,第二条边是已经匹配的边,如此未匹配和已匹配的边交替出现,最后一条边仍然是未匹配边(注意P可以是只有一条未匹配边的路径)。根据增广路径的附加条件可以看出一个特点:P的未匹配边一定比已匹配边多一条。
三,匈牙利算法依次对二分图的半边(左半边或者右半边,条件是节点数少的一边)的每个节点开始找增广路径,如果找到则取反:未匹配的边变成匹配边,已匹配边去掉匹配关系。这样的结果是路径P的匹配边数量增加一条,未匹配边数量减少一条。寻找增广路径的方法为DFS或者BFS递归。
四,当二分图中不存在增广路径时即产生最大匹配数。
匈牙利算法的实质就是找增广路径,并对增广路径做取反操作,直到没有增广路径为止。
匈牙利算法的基本流程:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define GSIZE 251 5 6 typedef struct{ 7 int queue[GSIZE]; 8 int head; 9 int tail; 10 }QUEUE; 11 12 int vtx, eg; 13 QUEUE q; 14 int color[GSIZE], par[GSIZE]; 15 int resNet[GSIZE][GSIZE]; //模拟链表:y轴为节点索引,每一行存放此节点指向的节点索引, 16 //若为-1则说明指向的节点为空 17 int InitQueue(){ 18 q.head=q.tail=0; 19 return 1; 20 } 21 int EnQueue(int x){ 22 q.queue[q.tail]=x; 23 q.tail++; 24 return 1; 25 } 26 int DeQueue(){ 27 int x; 28 x=q.queue[q.head]; 29 q.head++; 30 return x; 31 } 32 33 int BFSFindPath() 34 { 35 int flag, i, u, v; 36 flag=0; 37 InitQueue(); 38 for (i=1;i<=vtx;i++){ 39 color[i]=color[i+120]=0; 40 par[i]=par[i+120]=-1; 41 } 42 color[250]=0; 43 par[250]=-1; 44 color[0]=1; 45 par[0]=-1; 46 EnQueue(0); 47 while (q.head!=q.tail && flag==0){ 48 u=DeQueue(); 49 i=0; 50 while (resNet[u][i]!=-1 && resNet[u][i]!=0 && i<GSIZE){ 51 v=resNet[u][i]; 52 if (color[v]==0){ 53 color[v]=1; 54 par[v]=u; 55 EnQueue(v); 56 } 57 if (v==250){//当搜索到一条最短路径后停止 58 flag=1; 59 break; 60 } 61 i++; 62 } 63 color[u]=2; 64 } 65 return flag; 66 } 67 int Ford_Fulkerson() 68 { 69 int pathNum, v, i, del; 70 pathNum=0; 71 while (BFSFindPath()){ 72 v=250; 73 //par[v]---->v修改为v--->par[v] 74 while (par[v]!=-1){ 75 i=0; 76 while (resNet[v][i]!=-1 && i<GSIZE){ 77 i++; 78 } 79 resNet[v][i]=par[v]; 80 i=0; 81 while (resNet[par[v]][i]!=-1 && i<GSIZE){ 82 if (resNet[par[v]][i]==v){ 83 del=i; 84 } 85 i++; 86 } 87 resNet[par[v]][del]=resNet[par[v]][i-1]; 88 resNet[par[v]][i-1]=-1; 89 90 v=par[v]; 91 } 92 pathNum++; 93 } 94 return pathNum; 95 } 96 int main() 97 { 98 int c, i, st, end, cnt, ans; 99 //freopen("input.txt", "r", stdin); scanf("%d", &c); while (c--){ memset(resNet, -1, sizeof(resNet)); scanf("%d %d", &vtx, &eg); //设起点下标0,终点下标250,构造剩余网络 for (i=1;i<=vtx;i++){ resNet[0][i-1]=i; resNet[i+120][0]=250; } for (i=1;i<=eg;i++){ cnt=0; scanf("%d %d", &st, &end); while (resNet[st][cnt]!=-1){ cnt++; } resNet[st][cnt]=end+120; } if (eg==0){ ans=vtx; } else{ ans=vtx-Ford_Fulkerson(); } printf("%d\n", ans); } return 0; }
相关文章推荐
- POJ 1422 Air Raid (二分图最小点集覆盖 匈牙利算法)
- POJ-1422-Air Raid-求最小路径覆盖(匈牙利算法)
- POJ 1422 Air Raid(匈牙利算法—最小路径覆盖)
- POJ 1422 Air Raid 及 关于匈牙利算法的理解的小比喻
- 利用匈牙利算法&Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES
- POJ 1469 COURSES (二分图最大匹配 匈牙利算法)
- poj题目1469 COURSES (二分图匹配,匈牙利算法)
- poj_1469 COURSES匈牙利算法
- zoj 1140 poj 1469 COURSES(二分图匹配 匈牙利算法)
- POJ:1469 COURSES(匈牙利算法模版题)
- POJ-1469 COURSES ( 匈牙利算法 dfs + bfs )
- poj&nbsp;1422&nbsp;Air&nbsp;Raid(匈牙利&nbsp;DAC图最…
- poj 1469 COURSES(匈牙利算法模板)
- POJ 1469-COURSES(二分图匹配入门-匈牙利算法)
- 匈牙利扩展 - Air Raid POJ - 1422
- poj 1469 COURSES 二分图最大匹配 匈牙利算法
- POJ 1469 COURSES【匈牙利算法入门 二分图的最大匹配 模板题】
- poj1469 COURSES(匈牙利算法)(解题报告)
- POJ 1469 COURSES【匈牙利算法入门 二分图的最大匹配 模板题】
- poj 1469 COURSES 匈牙利算法