poj 2195 Going Home 二分图最小权匹配KM算法

题意:

有n个人要回到n间房子里,每间房子只允许一个人,求n个人要走的最小距离和。

分析:

裸的二分图最小权匹配,KM搞之。

代码:

//poj 2195
//sep9
#include <iostream>
using namespace std;
const int maxN=128;
char g[maxN][maxN];
int mx[maxN],my[maxN],hx[maxN],hy[maxN];
int w[maxN][maxN];
int lx[maxN],ly[maxN],linky[maxN];
int visx[maxN],visy[maxN];
int slack[maxN];
int nx,ny;

bool find(int x)
{
	visx[x]=true;
	for(int y=0;y<ny;++y){
		if(visy[y])
			continue;
		int t=lx[x]+ly[y]-w[x][y];
		if(t==0){
			visy[y]=true;
			if(linky[y]==-1||find(linky[y])){
				linky[y]=x;
				return true;
			}
		}
		else if(slack[y]>t)
			slack[y]=t;
	}
	return false;
}

int KM()
{
	int i,j;
	memset(linky,-1,sizeof(linky));
	memset(ly,0,sizeof(ly));
	for(i=0;i<nx;++i)
		for(j=0,lx[i]=INT_MIN;j<ny;++j)
			if(w[i][j]>lx[i])
				lx[i]=w[i][j];
	for(int x=0;x<nx;++x){
		for(i=0;i<ny;++i)
			slack[i]=INT_MAX;
		while(1){
			memset(visx,0,sizeof(visx));
			memset(visy,0,sizeof(visy));
			if(find(x))
				break;
			int d=INT_MAX;
			for(i=0;i<ny;++i)
				if(!visy[i]&&slack[i]<d)
					d=slack[i];
			if(d==INT_MAX)
				return -1;
			for(i=0;i<nx;++i)
				if(visx[i])
					lx[i]-=d;
			for(i=0;i<ny;++i)
				if(visy[i])
					ly[i]+=d;
				else
					slack[i]-=d;
		}
	}
	int result=0;
	for(i=0;i<ny;++i)
		if(linky[i]>-1)
			result+=w[linky[i]][i];
	return result;
}

int main()
{
	int i,j,n,m;
	while(scanf("%d%d",&n,&m)==2){
		if(n==0&&m==0)
			break;
		for(i=0;i<n;++i)
			scanf("%s",g[i]);
		int mcnt=0,hcnt=0;
		for(i=0;i<n;++i)
			for(j=0;j<m;++j)
				if(g[i][j]=='m'){
					mx[mcnt]=i;
					my[mcnt]=j;
					++mcnt;
				}
				else if(g[i][j]=='H'){
					hx[hcnt]=i;
					hy[hcnt]=j;
					++hcnt;
				}
		for(i=0;i<mcnt;++i)
			for(j=0;j<hcnt;++j){
				w[i][j]=abs(mx[i]-hx[j])+abs(my[i]-hy[j]);
				w[i][j]=-w[i][j];
			}
		nx=ny=mcnt;
		printf("%d\n",-KM());
	}
	return 0;
} 
时间: 2024-12-24 06:37:41

poj 2195 Going Home 二分图最小权匹配KM算法的相关文章

POJ 2195 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了 先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配. 如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d. 这样两个点都在交替路中的时候x[i]+y[i]的和不边 X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配. X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中.

[ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receivesN orders for toys. The man

poj 3686 The Windy&#39;s 二分图最小权和匹配KM

题意: 给n个玩具和m家工厂,每个玩具只能在一家工厂加工,给出每个玩具在每家工厂需要的加工时间,求这n个玩具完成时间平均值的最小值. 分析: 求最小和容易联系到二分图的最小权和匹配,这题的问题是n与m的大小关系是不确定的,也是就是说可能会有多个玩具到同一家工厂里加工的情况,这似乎与匹配的定义相矛盾.但仔细一想,如果多个玩具在同一工厂加工,他们的完成时间肯定是不一样的,所以讲w[i][j]=z 拆成w[i][0*m+j]=z,w[i][1*m+j]=2*z,w[i][2*m+j]=3*z.....

[ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2963    Accepted Submission(s): 1492 Problem Description On a grid map there are n little men and n houses. In each unit time, every

POJ 1325 Machine Schedule (二分图最小点集覆盖 匈牙利算法)

Machine Schedule Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12621   Accepted: 5399 Description As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduli

二分图 最大权匹配 km算法

这个算法的本质还是不断的找增广路: KM算法的正确性基于以下定理:若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配. 这个定理是显然的.因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和:如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和.所以相等子图的完备匹配一定是二分图的最大权匹配. (1)可行点标:每个点有一个标号,记lx[i]为X方点i的标号,l

HDU 3722 Card Game(二分图最佳完美匹配+KM算法)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3722 1 /* 2 问题 3 将任意的两个字符串进行匹配,使得匹配后权值和最大 4 5 解题思路 6 将任意的字符串的权值计算出来,使用KM算法即可. 7 */ 8 #include<cstdio> 9 #include<cstring> 10 #include<algorithm> 11 using namespace std; 12 13 const int maxn

二分图最大权匹配(KM算法)

#80. 二分图最大权匹配 统计 描述 提交 自定义测试 从前一个和谐的班级,有 $n_l$ 个是男生,有 $n_r$ 个是女生.编号分别为 $1, \dots, n_l$ 和 $1, \dots, n_r$. 有若干个这样的条件:第 $v$ 个男生和第 $u$ 个女生愿意结为配偶,且结为配偶后幸福程度为 $w$. 请问这个班级里幸福程度之和最大是多少? 输入格式 第一行三个正整数,$n_l, n_r, m$. 接下来 $m$ 行,每行三个整数 $v, u, w$ 表示第 $v$ 个男生和第 $

HDU 1533 二分图最小权匹配 Going Home

带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <map> 6 #include <vector> 7 #include <cmath> 8 #define MP