hdu 1533 二分图的完备匹配(KM算法)
来源:互联网 发布:java书号书名 编辑:程序博客网 时间:2024/04/28 10:57
http://acm.hdu.edu.cn/showproblem.php?pid=1533
#include"iostream"
#include"algorithm"
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
#define max_int 0x7fffffff
using namespace std;
const int N = 200;
int mm[2][N];
int hh[2][N];
int mh[N][N];
int n,m;
int lx[N],ly[N];//标号
char visitx[N],visity[N];//用于深度搜索,同时可以标记S和T集合的点
int mat[N];//mat[y] = x;表示集合Y的y点的匹配为x
int slack[N];//slack[x]保存相对与顶点x的最小al,初始时为无穷大,dfs寻找增广路径的时候不断更新,并且会越来越小
int nx,ny;
typedef struct position
{
int x;
int y;
}NODE;
int find(int x)
{
int t,y;
visitx[x] = 1;
for(y = 1;y<=ny;y++)
{
if(!visity[y]&&mh[x][y]!=0)
{
t = lx[x]+ly[y]-mh[x][y];
if(t!=0)
{
slack[x] = min(slack[x],t);
}
else
{
visity[y] = 1;
if((mat[y]==-1||find(mat[y])))
{
mat[y] = x;
return 1;
}
}
}
}
return 0;
}
//寻找最优匹配
void find1()
{
int s;
int x,y;
int min_al;
for(s = 1;s<=nx;)
{
for(;;)
{
memset(visitx,0,sizeof(visitx));
memset(visity,0,sizeof(visity));
if(find(s))
{
s++;
break;
}
//在S集合中找到最小的lx[x]+ly[y]-weight[x][y],借助slack数组
min_al = max_int;
for(x = 1;x<=nx;x++)
{
if(visitx[x]&&slack[x]<min_al)
{
min_al = slack[x];
}
}
//更新S集合和T集合顶点标号
for(x = 1;x<=nx;x++)
{
if(visitx[x])
lx[x] -=min_al;
}
for(y = 1;y<=ny;y++)
{
if(visity[y])
ly[y] +=min_al;
}
}
}
}
//求得最大(小)权值
void sumy(int &sum)
{
int cost = 0;
int x,y;
for(x = 1;x<=nx;x++)
{
cost+=lx[x];
}
for(y = 1;y<=ny;y++)
{
cost+=ly[y];
}
sum = cost;
}
int main()
{
int i,j;
char c;
int k,l;
int sum;
while(scanf("%d%d",&n,&m)!=EOF)
{
k = 0;
l = 0;
if(n==0&&m==0)
break;
for(i = 0;i<n;i++)
{
for(j = 0;j<m;j++)
{
cin>>c;
if(c=='m')
{
mm[0][k] = i;
mm[1][k] = j;
k++;
}
if(c=='H')
{
hh[0][l] = i;
hh[1][l] = j;
l++;
}
}
}
memset(ly,0,sizeof(ly));
for(i = 0;i<=k;i++)
{
mat[i] = -1;
lx[i] = -20000;
slack[i] = max_int;
}
for(i = 0;i<k;i++)
{
for(j = 0;j<l;j++)
{
mh[i+1][j+1] = abs(mm[0][i]-hh[0][j])+abs(mm[1][i]-hh[1][j]);
mh[i+1][j+1] *=-1;
// lx[i+1] = max(lx[i+1],mh[i+1][j+1]);
}
}
nx = ny = k;
for(i = 1;i<=ny;i++)
{
for(j = 1;j<=ny;j++)
{
lx[i] = max(lx[i],mh[i][j]);
}
}
sum = 0;
find1();
sumy(sum);
printf("%d\n",-1*sum);
}
return 0;
}
- hdu 1533 二分图的完备匹配(KM算法)
- hdu 3722 二分图 最优完备匹配 KM算法
- HDU 3488--Tour(二分图最小完备匹配,KM算法)
- KM算法求带权二分图的最大匹配(完备匹配)
- KM算法(二分图完备匹配下的最大权匹配)
- HDU2255 奔小康赚大钱(二分图的最大完备匹配,KM算法)
- KM算法(完备匹配下的最大权匹配)
- LA4043 - Ants(二分图完备最佳匹配KM)
- hdu 3488 Tour(二分匹配 最小权完备匹配 km算法)
- hdu 2255 二分图的完备匹配
- poj 2195 KM算法(完备匹配)
- HDU 2255-奔小康赚大钱(Kuhn-Munkras算法/KM算法-完备匹配下的最大权匹配)
- hdu 1533 KM算法 二分图最优匹配
- HDU3488 Tour(二分图最小完备匹配,KM算法,转化思想)
- 二分图完备匹配(最小费用 || KM) poj 2195 GoingHome
- 理论: 图论(11): 二分图的最大权匹配(KM算法)HDU 2255
- KM算法 二分图的最佳匹配
- 二分图的最佳匹配(KM 算法)
- Java的ClassLoader与Package机制(Prohibited package name:XXX)
- Unix_Linux学习(1)——vim编辑器的使用学习
- java中获得当前文件大小
- 直接由Java获取文件的创建时间
- Something more about ClassLoader
- hdu 1533 二分图的完备匹配(KM算法)
- Android 适配器Adapter的学习
- ajaxPro.dll基础教程(前台调用后台方法,后台调用前台方法)
- 学习笔记18 复习asp.net页面传参数的几种方式
- 索引create|rebuild|rebulid online
- 编译uboot与内核
- BugFree登录Call-time问题
- xerces 读写 xml问题
- java 获取文件夹大小,文件大小,文件个数