hdu2813 One fihgt one (KM最小权值和)
2013-09-10 08:38
246 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2813
题解:KM模版题
#include <stdio.h>
#include <string.h>
#include <math.h>
#define INF 0x3f3f3f3f
#define MAXN 201
int w[MAXN][MAXN],match[MAXN];
int lx[MAXN],ly[MAXN],slack[MAXN];
int visitx[MAXN],visity[MAXN];
int nx,ny;
char LvBu[MAXN][21],CaoCao[MAXN][21];
int find(int x)
{
int i,temp;
visitx[x]=1;
for(i=1;i<=ny;++i)
{
if(visity[i])
continue;
temp=lx[x]+ly[i]-w[x][i];
if(temp==0)
{
visity[i]=1;
if(match[i]==-1||find(match[i]))
{
match[i]=x;
return 1;
}
}
else if(slack[i]>temp)
{
slack[i]=temp;
}
}
return 0;
}
int KM()
{
int i,j,d,ans;
memset(ly,0,sizeof(ly));
memset(match,-1,sizeof(match));
for(i=1;i<=nx;++i)
{//lx初始化为与它关联边中最大的
lx[i]=w[i][1];
for(j=2;j<=ny;++j)
if(w[i][j]>lx[i])
lx[i]=w[i][j];
}
for(i=1;i<=nx;++i)
{
for(j=1;j<=ny;++j)
slack[j]=INF;
while(1)
{
memset(visitx,0,sizeof(visitx));
memset(visity,0,sizeof(visity));
if(find(i))
break;
d=INF;
for(j=1;j<=ny;++j)
{
if(!visity[j]&&d>slack[j])
d=slack[j];
}
for(j=1;j<=nx;++j)
{
if(visitx[j])
lx[j]-=d;
}
for(j=1;j<=ny;++j)
{
if(visity[j])
ly[j]+=d;
else
slack[j]-=d;
}
}
}
ans=0;
for(i=1;i<=ny;++i)
{
if(match[i]!=-1)
ans+=w[match[i]][i];
}
return ans;
}
int check(char *s,int flag)
{
int i;
if(flag)
{
for(i=1;i<MAXN;++i)
{
if(strcmp(LvBu[i],s)==0)
return i;
if(strcmp(LvBu[i],"")==0)
{
strcpy(LvBu[i],s);
return i;
}
}
}
else
{
for(i=1;i<MAXN;++i)
{
if(strcmp(CaoCao[i],s)==0)
return i;
if(strcmp(CaoCao[i],"")==0)
{
strcpy(CaoCao[i],s);
return i;
}
}
}
}
int main()
{
int i,j,k,ans,val,x,y;
char str1[21],str2[21];
while(scanf("%d %d %d",&nx,&ny,&k)!=EOF)
{
memset(LvBu,'\0',sizeof(LvBu));
memset(CaoCao,'\0',sizeof(CaoCao));
for(i=1;i<=nx;++i)
{
for(j=1;j<=ny;++j)
w[i][j]=(~INF+1);
}
while(k--)
{
scanf("%s %s %d",str1,str2,&val);
x=check(str1,1);
y=check(str2,0);
w[x][y]=(~val+1);//取反
}
ans=KM();
printf("%d\n",(~ans+1));
}
return 0;
}
题解:KM模版题
#include <stdio.h>
#include <string.h>
#include <math.h>
#define INF 0x3f3f3f3f
#define MAXN 201
int w[MAXN][MAXN],match[MAXN];
int lx[MAXN],ly[MAXN],slack[MAXN];
int visitx[MAXN],visity[MAXN];
int nx,ny;
char LvBu[MAXN][21],CaoCao[MAXN][21];
int find(int x)
{
int i,temp;
visitx[x]=1;
for(i=1;i<=ny;++i)
{
if(visity[i])
continue;
temp=lx[x]+ly[i]-w[x][i];
if(temp==0)
{
visity[i]=1;
if(match[i]==-1||find(match[i]))
{
match[i]=x;
return 1;
}
}
else if(slack[i]>temp)
{
slack[i]=temp;
}
}
return 0;
}
int KM()
{
int i,j,d,ans;
memset(ly,0,sizeof(ly));
memset(match,-1,sizeof(match));
for(i=1;i<=nx;++i)
{//lx初始化为与它关联边中最大的
lx[i]=w[i][1];
for(j=2;j<=ny;++j)
if(w[i][j]>lx[i])
lx[i]=w[i][j];
}
for(i=1;i<=nx;++i)
{
for(j=1;j<=ny;++j)
slack[j]=INF;
while(1)
{
memset(visitx,0,sizeof(visitx));
memset(visity,0,sizeof(visity));
if(find(i))
break;
d=INF;
for(j=1;j<=ny;++j)
{
if(!visity[j]&&d>slack[j])
d=slack[j];
}
for(j=1;j<=nx;++j)
{
if(visitx[j])
lx[j]-=d;
}
for(j=1;j<=ny;++j)
{
if(visity[j])
ly[j]+=d;
else
slack[j]-=d;
}
}
}
ans=0;
for(i=1;i<=ny;++i)
{
if(match[i]!=-1)
ans+=w[match[i]][i];
}
return ans;
}
int check(char *s,int flag)
{
int i;
if(flag)
{
for(i=1;i<MAXN;++i)
{
if(strcmp(LvBu[i],s)==0)
return i;
if(strcmp(LvBu[i],"")==0)
{
strcpy(LvBu[i],s);
return i;
}
}
}
else
{
for(i=1;i<MAXN;++i)
{
if(strcmp(CaoCao[i],s)==0)
return i;
if(strcmp(CaoCao[i],"")==0)
{
strcpy(CaoCao[i],s);
return i;
}
}
}
}
int main()
{
int i,j,k,ans,val,x,y;
char str1[21],str2[21];
while(scanf("%d %d %d",&nx,&ny,&k)!=EOF)
{
memset(LvBu,'\0',sizeof(LvBu));
memset(CaoCao,'\0',sizeof(CaoCao));
for(i=1;i<=nx;++i)
{
for(j=1;j<=ny;++j)
w[i][j]=(~INF+1);
}
while(k--)
{
scanf("%s %s %d",str1,str2,&val);
x=check(str1,1);
y=check(str2,0);
w[x][y]=(~val+1);//取反
}
ans=KM();
printf("%d\n",(~ans+1));
}
return 0;
}
相关文章推荐
- HDOJ 2813 - One fihgt one KM求最小权最大匹配..
- hdu 2813 One fihgt one(二分图最小权匹配KM)
- hdu 2813 One fihgt one【KM 最小匹配】
- HDU-2813 One fihgt one 最小权匹配
- hdu 1853 Cyclic Tour(KM 最小权值匹配)
- hdu 1533 Going Home(KM 最小权值匹配)
- One fihgt one hdu 2813 map+二分图最优匹配+KM快速模板
- HDU 2813 One fihgt one KM小变形
- hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)
- hdu3488 Tour (KM最小权值和)
- poj2195_KM最小权值和
- HDU 2813 One fihgt one(KM最大匹配)
- POJ 2195 Going Home(BFS+KM求最小权值)
- poj 3686 The Windy's 二分图最小权和匹配KM
- uva 11090 Going in Cycle!! 平均权值最小的回路
- [CareerCup] 18.6 Smallest One Million Numbers 最小的一百万个数字
- ural 1076 KM求最小权匹配
- HDU-2813 One fihgt one【二分图最优匹配】
- 最小权值和
- uva 1411 Ants (权值和最小的完美匹配---KM算法)