One fihgt one
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2579 Accepted Submission(s): 821
Problem Description
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.
Input
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.
Output
One integer , the least injuries Lv Bu’s generals would get.
Sample Input
2 3 5
LvBu ZhangFei 6
LvBu GuanYu 5
LvBu XuChu 4
ZhangLiao ZhangFei 8
ZhangLiao XuChu 3
Sample Output
8
Author
shǎ崽
Source
HDU 1st “Old-Vegetable-Birds Cup” Programming Open Contest
题目大意:左集合有n个大将,右集合有m个大将,有k个打斗关系,问左集合最小受到的伤害,规则当然是一打一,而且打完了就不用再换别人去打了。
思路:
1、裸的KM匹配问题,问的其实就是最小匹配,那么因为我们要求的是最小匹配,那么我们可以直接将输入进来的权值取反,这样原先的最大值就变成了最小值,那么这个时候我们再进行一次KM求最大匹配,然后将最大匹配值取反即可、
2、因为题目中保证了m>=n,所以我们直接用n去匹配m即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<map>
#include<iostream>
using namespace std;
int a[500][500];
int nn,mm,k,n;
char aa[5000];
char bb[5000];
int lx[500];
int ly[500];
int vx[500];
int vy[500];
int match[500];
int low;
int find(int u)
{
vx[u]=1;
for(int i=1;i<=mm;i++)
{
if(vy[i]==1)continue;
int tmp=lx[u]+ly[i]-a[u][i];
if(tmp==0)
{
vy[i]=1;
if(match[i]==-1||find(match[i]))
{
match[i]=u;
return 1;
}
}
else if(tmp<low)low=tmp;
}
return 0;
}
void KM()
{
memset(match,-1,sizeof(match));
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(int i=1;i<=nn;i++)
{
for(int j=1;j<=mm;j++)
{
a[i][j]=-a[i][j];
lx[i]=max(lx[i],a[i][j]);
}
}
for(int i=1;i<=nn;i++)
{
while(1)
{
low=0x3f3f3f3f;
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
if(find(i))break;
for(int j=1;j<=nn;j++)
{
if(vx[j])lx[j]-=low;
}
for(int j=1;j<=mm;j++)
{
if(vy[j])ly[j]+=low;
}
}
}
int sum=0;
for(int i=1;i<=mm;i++)
{
//printf("%d\n",match[i]);
if(match[i]==-1)continue;
sum+=a[match[i]][i];
}
printf("%d\n",-sum);
}
int main()
{
while(~scanf("%d%d%d",&nn,&mm,&k))
{
memset(a,0x3f3f3f3f,sizeof(a));
map<string, int >s;
map<string, int >ss;
int cont1=1;
int cont2=1;
for(int i=0;i<k;i++)
{
int w;
scanf("%s%s%d",aa,bb,&w);
if(s[aa]==0)
{
s[aa]=cont1++;
}
if(ss[bb]==0)
{
ss[bb]=cont2++;
}
int u=s[aa],v=ss[bb];
a[u][v]=w;
}
KM();
}
}