二分图KM算法 POJ 2195
来源:互联网 发布:虹口js漂亮的油压店 编辑:程序博客网 时间:2024/05/21 17:59
暴力(n^3)
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;#define MAX 105#define INF 9999999struct House { int r, c; } house[MAX];struct Man { int r, c; } man[MAX];int H, M, n, m;int A[MAX], B[MAX];int visA[MAX], visB[MAX];int match[MAX], slack[MAX], map[MAX][MAX];bool find_path ( int i ){visA[i] = true;for ( int j = 0; j < H; j++ ){if ( !visB[j] && A[i] + B[j] == map[i][j] ){visB[j] = true;if (match[j] == -1 || find_path(match[j])){match[j] = i;return true;}}else if ( A[i] + B[j] > map[i][j] ) //j属于B,且不在交错路径中slack[j] = min(slack[j], A[i]+B[j]-map[i][j]);}return false;}void KM (){ int i, j, d; memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); memset(match,-1,sizeof(match)); for ( i = 0; i < M; i++ ) for ( j = 0; j < H; j++ ) A[i] = max (map[i][j], A[i]); for ( i = 0; i < M; i++ ) { for ( j = 0; j < H; j++ ) slack[j] = INF; while ( 1 ) { memset(visA,0,sizeof(visA)); memset(visB,0,sizeof(visB)); if ( find_path ( i ) ) break; //从i点出发找到交错路径则跳出循环 for ( d = INF, j = 0; j < H; j++ ) //取最小的slack[j] if (!visB[j] && d > slack[j]) d = slack[j]; for ( j = 0; j < M; j++ ) //集合A中位于交错路径上的-d if ( visA[j] ) A[j] -= d; for ( j = 0; j < H; j++ ) //集合B中位于交错路径上的+d if ( visB[j] ) B[j] += d; else slack[j] -= d; //注意修改不在交错路径上的slack[j] } }}int main(){ char s[MAX];int i, j, res;while ( scanf("%d%d",&n,&m) ){ if ( !m && !n ) break;H = M = res = 0;for ( i = 0; i < n; i++ ){scanf("%s",s);for ( j = 0; j < m; j++ ){if ( s[j] == 'H' ) house[H].r = i, house[H++].c = j;else if ( s[j] == 'm' )man[M].r = i, man[M++].c = j;}}for ( i = 0; i < M; i++ ) //求最小带权匹配可以将权值改为负数for ( j = 0; j < H; j++ )map[i][j] = -(abs(man[i].r-house[j].r) + abs(man[i].c-house[j].c)); KM();for ( j = 0; j < H; j++ )res -= map[match[j]][j];printf("%d\n",res);}return 0;}
KM算法
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 105;const int INF = 1<<29;int w[maxn][maxn];int n;int ly[maxn],lx[maxn];//顶标bool S[maxn],T[maxn]; //左/右第i个点是否已经标记int left[maxn]; //匹配为右边第i个点的编号int H, M;int R,C;bool match(int i){ S[i]=1; for(int j=1;j<=n;j++) if(lx[i]+ly[j]==w[i][j]&&!T[j]){ T[j]=1; if(!left[j]||match(left[j])){ left[j]=i; return true; } } return false;}void update(){ int a=INF; for(int i=1;i<=n;i++){ if(S[i]) for(int j=1;j<=n;j++){ if(!T[j]) a=min(a,lx[i]+ly[j]-w[i][j]); } } for(int i=1;i<=n;i++){ if(S[i]) lx[i]-=a; if(T[i]) ly[i]+=a; }}void KM(){ for(int i=1;i<=n;i++){ left[i]=lx[i]=ly[i]=0; for(int j=1; j<=n;j++){ lx[i]=max(lx[i],w[i][j]); } } for(int i=1;i<=n;i++){ while(1){ //printf("1"); memset(T,0,sizeof(T)); memset(S,0,sizeof(S)); if(match(i)) break; else update(); } }}struct House { int r, c; } house[maxn];struct Man { int r, c; } man[maxn];int main(){ char s[maxn];int i, j;while ( scanf("%d %d",&R,&C) ){ if ( !R && !C ) break;H = M = 1;for ( i = 1; i <=R; i++ ){scanf("%s",s+1);for ( j = 1; j <=C; j++ ){if ( s[j] == 'H' ) house[H].r = i, house[H++].c = j;else if ( s[j] == 'm' )man[M].r = i, man[M++].c = j;}}for ( i = 1; i <= M-1; i++ ) //求最小带权匹配可以将权值改为负数for ( j = 1; j <= H-1; j++ )w[i][j] = -(abs(man[i].r-house[j].r) + abs(man[i].c-house[j].c)); n=H-1; KM(); int res=0;for ( j = 1; j <=H-1; j++ )res -= w[left[j]][j];printf("%d\n",res);}return 0;}
0 0
- 二分图KM算法 POJ 2195
- poj 2195 二分图最优匹配 KM算法求最小值
- POJ 2195 二分图最小权匹配KM算法
- poj 2195 Going Home(二分图最优匹配KM算法)
- poj 2195 二分图最优匹配KM算法 模板题
- HDU&POJ训练记录3 二分图KM算法
- poj 2195 KM算法
- POJ 2195 Going Home【KM算法-二分图的最优匹配】
- POJ 2195 Going Home(KM算法——二分图最小权匹配)
- POJ 2195 Going Home (二分图最大权匹配、KM算法)
- poj 2195 Going Home 二分图最小权匹配KM算法
- POJ 2195&&HDU 1533 Going Home(KM算法解决二分图最小权匹配)
- 二分图匹配【KM算法】
- 二分图 KM算法应用
- 二分图之KM算法
- 二分图完备匹配(最小费用 || KM) poj 2195 GoingHome
- poj 2195(KM算法模板)
- KM算法 二分图的最佳匹配
- Google最新Host
- 高质量软件开发之道
- 查看表空间物理文件的名称及大小
- 反渗透设备:反渗透设备的应用范围详细分析
- C++——STL所有算法介绍
- 二分图KM算法 POJ 2195
- Android ListView从网络获取图片及文字显示
- 华为U8860刷机包 CM11 Andorid 4.4.4 稳定流畅 推荐长期使用
- Eclipse下的java工程目录
- 为什么烧写了WinCE的系统重新烧写linux时候需要先将NAND FLASH全部擦除一遍之后再重新烧写linux
- apple的各种联系方式,原文链接http://www.cocoachina.com/market/20120207/3946.html
- 反渗透设备:反渗透设备应用的基本原理与技术优势
- java读写文件
- 【源码分享下载】每日更新之Android应用源码之仿微信5.2布局