POJ 2195 Going Home(二分图最优匹配)
来源:互联网 发布:q版地图制作软件 编辑:程序博客网 时间:2024/05/18 08:24
POJ 2195 Going Home(二分图最优匹配)
http://poj.org/problem?id=2195
题意:
给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致。man每移动一格需花费$1(即单位费用=单位距离),一间house只能入住一个man。现在要求所有的man都入住house,求最小费用。
分析:
每个人对应二分图左边的点,每个房间对应二分图右边的点.每个人与每个房间都有一条带权值的边,表示这个人到该房间的花费.
为了使得每个人都得到一个房间,且他们行走的开销最小.
那么本题求得就是该二分图的一个完备匹配且该匹配边的权值和最小了.
但是KM算法只能求二分图的最优匹配(即匹配边权值和最大的匹配),我们现在要求权值和最小的匹配怎么办?
我们只需要把所有边的权值取负即可。
假设存在一个最优(在所有解中花费ans最小,那么-ans自然最大)的解,那么当我们把所有权值取负之后,我们用KM算法得到的一个匹配的权值和必然就是那个最优的解(-ans最大)。因为KM算法不会漏掉权值和最大的那组解。(想想是不是)
最终用KM算法求出的就是我们所需的最小权值匹配的负数.
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100+5;struct Max_Match{ int W[maxn][maxn],n; int Lx[maxn],Ly[maxn]; bool S[maxn],T[maxn]; int left[maxn]; bool match(int i) { S[i]=true; for(int j=1;j<=n;j++)if(Lx[i]+Ly[j]==W[i][j] && !T[j]) { T[j]=true; if(left[j]==-1 || match(left[j])) { left[j]=i; return true; } } return false; } void update() { int a=1<<30; 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; } } int solve(int n) { this->n=n; memset(left,-1,sizeof(left)); for(int i=1;i<=n;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(true) { for(int j=1;j<=n;j++) S[j]=T[j]=false; if(match(i)) break; else update(); } } int ans=0; for(int i=1;i<=n;i++) ans+= W[left[i]][i]; return ans; }}KM;struct Node{ int x,y; Node(){} Node(int x,int y):x(x),y(y){}}node1[maxn],node2[maxn];int main(){ int R,C; while(scanf("%d%d",&R,&C)==2 && R) { int num1=0,num2=0; for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) { char c; scanf(" %c",&c); if(c=='H') node2[++num2]=Node(i,j); else if(c=='m') node1[++num1]=Node(i,j); } for(int i=1;i<=num1;i++) for(int j=1;j<=num2;j++) KM.W[i][j]=-( abs(node1[i].x-node2[j].x)+abs(node1[i].y-node2[j].y) );//取负值 int ans = KM.solve(num1); printf("%d\n",-ans);//取负值 } return 0;}
0 0
- POJ 2195 Going Home(二分图最优匹配)
- poj 2195 - Going Home 二分图最优匹配 ek
- POJ 2195 Going Home(二分图最优匹配)
- poj 2195 Going Home(二分图最优匹配KM算法)
- POJ 2195 Going Home(二分图最优匹配)
- 二分图的最优匹配 going home
- hdu1533 going home 二分图最优匹配
- POJ 2195 Going Home【KM算法-二分图的最优匹配】
- poj 2195 Going Home 二分图最大权匹配
- POJ 2195 - Going Home(二分图最大权匹配)
- poj 2195 going home二分图最大匹配
- POJ 2195 Going Home [二分图带权匹配] [费用流]
- 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算法解决二分图最小权匹配)
- 【poj2195】【二分图最佳匹配】Going Home
- 二进制数据流的处理,用memcpy
- 六大神器助力SaaS公司留住老用户
- iOS程序执行过程
- super 与this
- hdu 4974
- POJ 2195 Going Home(二分图最优匹配)
- validate rules custom
- 媒体移动化需抓住三大要素
- 如何降低白噪声对网站用户体验的影响
- 夯实基础——快速排序
- iOS- UI界面-传值
- 从创业失败中学到的七条教训
- 随手札记
- Protocol Buffer技术深入理解(C++实例)