您的位置:首页 > 其它

hdu 2813 One fihgt one(二分图最小权匹配KM)

2014-08-23 16:53 337 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2813

[align=left]Problem Description[/align]
Lv Bu and his soldiers are facing a cruel war——Cao Cao had his best generals just miles away.



There’s little time , but Lv Bu is unaware of how to arrange his warriors , what he know is that he have n brave generals while Cao Cao has m , and he has k fights to choose from , he’d like to make all his n warriors participate in the battle but get the least
injuries . Lv Bu is happy because there is always a good solution . So , now is your task to tell Lv Bu the least injuries his troop would get.

No one could take part in two fights.
 

[align=left]Input[/align]
Multiple cases. For each case ,there are three integers in the first line , namely n,m (1<=n<=m<=200)and k (n<=k<=m*n).

The next k lines are the information about k possible fights , for each line are two strings (no more than 20 characters ) and an integer. The first string indicates Lv Bu’s general and the second , of course , Cao Cao’s , and the integer is the injury Lv Bu’s
general would get if this fight were chosen.
 

[align=left]Output[/align]
One integer , the least injuries Lv Bu’s generals would get.
 

[align=left]Sample Input[/align]

2 3 5
LvBu ZhangFei 6
LvBu GuanYu 5
LvBu XuChu 4
ZhangLiao ZhangFei 8
ZhangLiao XuChu 3

 

[align=left]Sample Output[/align]

8

 

[align=left]Author[/align]
shǎ崽
 

[align=left]Source[/align]
HDU 1st “Old-Vegetable-Birds Cup” Programming
Open Contest

题意是吕布和曹操对战,给出两队的对战情况,要求吕布伤害最小,即求最小权匹配,建图用到了map,在读入的时候我用了cin,一直超时,改为scanf就AC了。。

代码:
#include<stdio.h>
#include<string.h>
#include<map>
#include<string>
#include<iostream>
using namespace std;
map<string,int>mp1;
map<string,int>mp2;
const int maxn=210;
const int inf=1<<31-1;
int n,m;
int w[maxn][maxn];
int lx[maxn],ly[maxn];
int sx[maxn],sy[maxn];
int match[maxn];
int nx,ny;
int find(int u)
{
sx[u]=1;
for(int v=1;v<=ny;v++)
{
if(!sy[v]&&lx[u]+ly[v]==w[u][v])
{
sy[v]=1;
if(match[v]==-1||find(match[v]))
{
match[v]=u;
return 1;
}
}
}
return 0;
}
int km()
{
for(int i=1;i<=nx;i++)
{
lx[i]=-inf;
for(int j=1;j<=ny;j++)
if(lx[i]<w[i][j])
lx[i]=w[i][j];
}
memset(ly,0,sizeof(ly));
memset(match,-1,sizeof(match));

for(int u=1;u<=nx;u++)
{
while(1)
{
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
if(find(u))
break;
int d=inf;
for(int i=1;i<=nx;i++)
if(sx[i])
for(int j=1;j<=ny;j++)
if(!sy[j]&&d>lx[i]+ly[j]-w[i][j])
d=lx[i]+ly[j]-w[i][j];
if(d==inf)
return -1;
for(int i=1;i<=nx;i++)
{
if(sx[i])
lx[i]-=d;
}
for(int i=1;i<=ny;i++)
{
if(sy[i])
ly[i]+=d;
}
}
}
int res=0;
for(int i=1;i<=ny;i++)
if(match[i]>=0)
res+=w[match[i]][i];
return -res;
}
int main()
{
//freopen("in.txt","r",stdin);
int p;
while(scanf("%d %d %d",&n,&m,&p)==3)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
w[i][j]=-inf;
mp1.clear();
mp2.clear();
nx=n;
ny=m;
int u=1,v=1;
while(p--)
{
char a[30],b[30];
int c;
scanf("%s%s%d",a,b,&c);
if(mp1.find(a)==mp1.end())
mp1[a]=u++;
if(mp2.find(b)==mp2.end())
mp2[b]=v++;
w[mp1[a]][mp2[b]]=-c;
}
int ans=km();
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: