• hdu 2813 One fihgt one【KM+STLmap】


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2813

    我的链接:http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=17728#problem/L

    算法思想:二分图的最优匹配求最小权覆盖,吕布的战将为集合一(二分图的行),曹操的战将为集合二(二分图的列),如果两边的战将间有战争就连边,建图。

                        然后直接套模板即可。

                        题目的关键是如何输入且存储两边的战将名字,这里用到了C++中STL的map容器,水过了。PS:大牛说字典树最快。

                       STL的map:

                                              头文件#include<map>
                                                          #include<string>
                                                          using namespace std;

                                             建立容器:map<string,int> m1;
                                                                 map<string,int> m2;

                                             清空容器:m1.clear();
                                                                 m2.clear();

                                             进入容器:if(mi[a]==0) m1[a]=k1++; (PS :之前k1要初始化,至于是0还是1就看你自己的模板了)

                                                                或者if(mi.find(a)==m1.end()) m1[a]=k1++;也一样。

    One fihgt one

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1665    Accepted Submission(s): 543


    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
     

    Recommend
    lcy
    注意:此题建立的图,不一定填满所有的边,所以开始时要把图初始化为大的负数。

                 另外要注意的就是不能直接套用以前的N*N的模板了,中间相应的地方注意自己改成m,看来有必要重写模板了啊!

    //Accepted	496 KB	734 ms	C++	1967 B	
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<iostream>
    using namespace std;
    map<string,int> m1;
    map<string,int> m2;
    const int maxn=210;
    int w[maxn][maxn];
    bool s[maxn],t[maxn];
    int lx[maxn],ly[maxn];
    int match[maxn];
    int n,m,k;
     
    bool hungary(int u){
         s[u]=true;
         for(int v=1;v<=m;v++){
             if(!t[v] && lx[u]+ly[v]==w[u][v]){
                t[v]=true;//易遗忘 
                if(match[v]==-1 || hungary(match[v])){
                   match[v]=u;
                   return true;
                }
             }
         }
         return false;
    }
    int KM(){
        int ans=0;
        memset(match,-1,sizeof(match));
        for(int i=1;i<=n;i++){
        	lx[i]=-1<<30;//注意 
        }
        memset(ly,0,sizeof(ly));
        for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
              lx[i]=max(lx[i],w[i][j]);
        for(int i=1;i<=n;i++){
            while(1){
               memset(s,false,sizeof(s));
               memset(t,false,sizeof(t));
               if(hungary(i)) break;
               else{
                    int a=1<<30;
                    for(int j=1;j<=n;j++) if(s[j]){
                        for(int k=1;k<=m;k++) if(!t[k] && a>lx[j]+ly[k]-w[j][k])
                            a=lx[j]+ly[k]-w[j][k];
                    }
                    for(int j=1;j<=n;j++){
                       if(s[j]) lx[j]-=a;   
                    }
                    for(int j=1;j<=m;j++){
                    	if(t[j]) ly[j]+=a;
                    }
               }
            }
        }
        for(int i=1;i<=m;i++) if(match[i]!=-1)//
    	    ans+=w[match[i]][i];
        return -ans;//易遗忘 
    }
    int main(){
    	char name1[21],name2[21];
    	int u,v,injury;
    	while(scanf("%d%d%d",&n,&m,&k)!=EOF){
    		m1.clear();
    		m2.clear();
    		u=v=1;
    		for(int i=1;i<=n;i++){//不要忘了初始化图,因为此题不一定会填满n*m的边 
    			for(int j=1;j<=m;j++)
    			w[i][j]=-1<<30;
    		}
    		while(k--){
    			scanf("%s%s%d",name1,name2,&injury);
    			if(m1.find(name1)==m1.end()) m1[name1]=u++;//若战将没有入图 
    			if(m2.find(name2)==m2.end()) m2[name2]=v++;
    			w[m1[name1]][m2[name2]]=-injury;
    		}
    		printf("%d\n",KM());
    	}
    	return 0;
    }
    


  • 相关阅读:
    用ssh整合时,用sessionfactory的getCurrentSession()获取不到session
    layim+signalr2.0+mongodb在线轻聊版解决方案(可提供演示)
    (绿色)修正版gooflow流程解决方案(源码分享+在线演示+UI地址下载)
    一个开源的可视化的jQuery工作流插件
    自定义流程gooflow.08 demo在线演示
    asp.net mvc 系统操作日志设计
    第三方系统平台如何对接gooflow2.0
    一个供新手把玩的jQueryUI在线文档
    Ninject 自动注册
    JQuery.imgAreaSelect 参数说明
  • 原文地址:https://www.cnblogs.com/freezhan/p/2950442.html
Copyright © 2020-2023  润新知