#include<iostream>//0(n^4)最小权匹配,KM算法
#include<stdio.h>
using namespace std;
struct node
{
int row;
int column;
}man[10002],home[10002];
int row,column,NumMan,NumHome;
int w[102][102],lx[102],ly[102],matchy[102];
bool visitx[102],visity[102];
bool dfs(int u)
{
int v;
visitx[u]=true;
for(v=1;v<=NumHome;v++)
{
if(visity[v]==false&&lx[u]+ly[v]==w[u][v])
{
visity[v]=true;
if(matchy[v]==0||dfs(matchy[v])==true)
{
matchy[v]=u;
return true;
}
}
}
return false;
}
int main()
{
int total;
int min;
int i,j,k;
char ch;
while(scanf("%d %d",&row,&column),row&&column)
{
getchar();
NumHome=1;
NumMan=1;
for(i=1;i<=row;i++)
{
for(j=1;j<=column;j++)
{
if((ch=getchar())=='m')
{
man[NumMan].row=i;
man[NumMan++].column=j;
}
else if(ch=='H')
{
home[NumHome].row=i;
home[NumHome++].column=j;
}
}
getchar();
}
NumMan--;
NumHome--;
memset(w,0,sizeof(w));
for(i=1;i<=NumMan;i++)
for(j=1;j<=NumHome;j++)
{
w[i][j]=abs(man[i].row-home[j].row)+abs(man[i].column-home[j].column);
}
memset(lx,127,sizeof(lx));
memset(ly,0,sizeof(ly));
for(i=1;i<=NumMan;i++)
for(j=1;j<=NumHome;j++)
{
if(w[i][j]<lx[i])
{
lx[i]=w[i][j];//如果是最大权匹配,则取最大值
}
}
memset(matchy,0,sizeof(matchy));
for(i=1;i<=NumMan;i++)
{
while(1)
{
memset(visitx,0,sizeof(visitx));
memset(visity,0,sizeof(visity));
//memset(&min,127,sizeof(min));
min=10000000;
if(dfs(i))
break;
for(j=1;j<=NumMan;j++)
{
if(visitx[j])
{
for(k=1;k<=NumHome;k++)
{
if(visity[k]==false&&((w[j][k]-ly[k]-lx[j])<min))//lx[i]+ly[j]>=w[i,j](最大权), lx[i]+ly[j]<=W[i](最小权)
{
min=w[j][k]-ly[k]-lx[j];
}
}
}
}
for(k=1;k<=NumMan;k++)
{
if(visitx[k])
{
lx[k]+=min;
}
}
for(k=1;k<=NumHome;k++)
{
if(visity[k])
{
ly[k]-=min;
}
}
}
}
total=0;
for(i=1;i<=NumHome;i++)
{
total+=w[matchy[i]][i];
}
printf("%d/n",total);
}
return 0;
}
poj 2594(二分图最优匹配)
最新推荐文章于 2019-09-11 17:17:35 发布
2094

被折叠的 条评论
为什么被折叠?



