zoukankan      html  css  js  c++  java
  • hdu2813:One fihgt one(KM匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2813

    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

    题意分析:

    吕布和曹操对决,吕布有n个武将,曹操有m个武将,武将之间对决会有伤害,吕布的每个武将都要上场,求吕布方受到的最小伤害值。

    解题思路:

    map函数存图,KM求最大匹配。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #define N 220
    using namespace std;
    int e[N][N], lx[N], ly[N], slack[N], march[N], bookx[N], booky[N], n, m, nx, ny, inf=99999999;
    map<string, int> a;
    map<string, int> b;
    int dfs(int u)
    {
    	bookx[u]=1;
    	int v, d;
    	for(v=1; v<=ny; v++)
    	{
    		if(!booky[v])
    		{
    			d=lx[u]+ly[v]-e[u][v];
    			if(d==0)
    			{
    				booky[v]=1;
    				if(march[v]==0 || dfs(march[v]))
    				{
    					march[v]=u;
    					return 1;
    				}	
    			}
    			else
    				slack[v]=min(slack[v], d);
    		}
    	}
    	return 0;
    }
    int KM()
    {
    	int i, j, x, d;
    	memset(ly, 0, sizeof(ly));
    	memset(march, 0, sizeof(march));
    	for(i=1; i<=nx; i++)
    	{
    		lx[i]=-inf;
    		for(j=1; j<=ny; j++)
    			lx[i]=max(lx[i], e[i][j]);
    	}
    	for(x=1; x<=nx; x++)
    	{
    		for(i=1; i<=ny; i++)
    			slack[i]=inf;
    		while(1)
    		{
    			memset(bookx, 0, sizeof(bookx));
    			memset(booky, 0, sizeof(booky));
    			if(dfs(x))
    				break;
    			d=inf;
    			for(i=1; i<=ny; i++)
    				if(!booky[i])
    					d=min(d, slack[i]);
    			for(i=1; i<=nx; i++)
    				if(bookx[i])
    					lx[i]-=d;
    			for(i=1; i<=ny; i++)
    			{
    				if(booky[i])
    					ly[i]+=d;
    				else
    					slack[i]-=d;
    			}
    		}
    	}
    	int sum=0;
    	for(i=1; i<=ny; i++)
    		sum+=e[march[i]][i];
    	return sum;
    }
    int main()
    {
    	int i, j, k, num;
    	char s1[N], s2[N];
    	while(scanf("%d%d%d", &n, &m, &k)!=EOF)
    	{
    		for(i=1; i<=n; i++)
    			for(j=1; j<=m; j++)
    				e[i][j]=-inf;
    		a.clear();
    		b.clear();
    		nx=0;
    		ny=0;
    		for(i=1; i<=k; i++)
    		{
    			scanf("%s%s%d", s1, s2, &num);
    			if(!a[s1])
    			{
    				nx++;
    				a[s1]=nx;
    			}
    			if(!b[s2])
    			{
    				ny++;
    				b[s2]=ny;	
    			}
    			e[a[s1]][b[s2]]=-num;
    		}
    		printf("%d
    ", -KM());
    	}
    	return 0;
    }
  • 相关阅读:
    为什么jdbc中的resultset只能取一次去第二次就报错了
    mapreduce中reduce中的迭代器只能调用一次。其实迭代器就只能调用一次
    Name node is in safe mode.
    mapreduce 查找共同好友
    mapreduce学习资料
    mysql 集合函数与where条件
    hive中order by,sort by, distribute by, cluster by作用以及用法
    二分类预测用的几个预测结果精确度计算方法
    矩阵乘法np.dot()及np.multipy()区别
    如何用matplotlib绘制决策边界
  • 原文地址:https://www.cnblogs.com/zyq1758043090/p/11852625.html
Copyright © 2011-2022 走看看