ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

pku 2195 KM算法求最小权二分匹配

2019-08-11 22:39:47  阅读:341  来源: 互联网

标签:slack pku int MAX KM 2195 usedy lx match


原文链接:http://www.cnblogs.com/ACAC/archive/2010/05/17/1737729.html
/*pku 2195 KM算法求最小权二分匹配*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAX 101
int hx[MAX],mx[MAX],hy[MAX],my[MAX];
char map[MAX][MAX];
int usedx[MAX],usedy[MAX],match[MAX],w[MAX][MAX],n,m;//// match[]存放的右顶点的匹配信息,w[][]存放的是权值,N是右顶点数
int lx[MAX],ly[MAX],slack[MAX];// lx[],ly[]分别存放的是左右顶标的信息,slack[]是松弛量
int k1,k2;
int dfs(int x)
{
usedx[x]=1;
for(int y=0;y<k2;y++)
{
if(!usedy[y])
{
int temp=lx[x]+ly[y]-w[x][y];
if(temp==0)
{
usedy[y]=1;
if(match[y]==-1 || dfs(match[y]))
{
match[y]=x;
return 1;
}
}
else
{
if(slack[y]>temp)
{
slack[y]=temp;
}
}
}
}
return 0;
}
void KM()
{
int i,j;
memset(match,-1,sizeof(match)); //match[]中存储的是y的匹配信息
for(i=0;i<k1;i++)
{
lx[i]=-999999999; //每个X节点的可行顶标设为它出发的所有弧的最大权
for(j=0;j<k2;j++)
{
if(lx[i]<w[i][j])
{
lx[i]=w[i][j];
}
}
}
memset(ly,0,sizeof(ly));
for(int x=0;x<k1;x++)
{
for(j=0;j<k2;j++)
{
slack[j]=999999999;
}
while(1)
{
memset(usedx,0,sizeof(usedx));
memset(usedy,0,sizeof(usedy));
if(dfs(x)) // 用匈牙利算法寻找完备匹配
{
break;
}
int min=99999999;
for(i=0;i<k2;i++)
{
if(!usedy[i] && min>slack[i])
{
min=slack[i];
}
}
for(i=0;i<k1;i++)
{
if(usedx[i])
{
lx[i]-=min;
}
}
for(i=0;i<k2;i++)
{
if(usedy[i])
{
ly[i]+=min;
}
else
{
slack[i]-=min;
}
}
}
}
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)!=EOF && n || m)
{
for(i=0;i<n;i++)
scanf("%s",map[i]);
k1=k2=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(map[i][j]=='m')
{
hx[k1]=i;
hy[k1++]=j;
}
else if(map[i][j]=='H')
{
mx[k2]=i;
my[k2++]=j;
}
}
}
for(i=0;i<k1;i++)
{
for(j=0;j<k2;j++)
{
w[i][j]=-(fabs(hx[i]-mx[j])+fabs(hy[i]-my[j]));
}
}
KM();
int ans=0;
for(i=0;i<k2;i++)
{
ans+=-w[match[i]][i];
}
printf("%d\n",ans);
}
return 0;
}

 

转载于:https://www.cnblogs.com/ACAC/archive/2010/05/17/1737729.html

标签:slack,pku,int,MAX,KM,2195,usedy,lx,match
来源: https://blog.csdn.net/weixin_30520015/article/details/99238773

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有