首页 > 其他 > 详细

HDU 2813

时间:2014-06-15 17:20:30      阅读:268      评论:0      收藏:0      [点我收藏+]

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

裸二分图最优匹配,需要用两个map把武将名字映射到点的序号上

bubuko.com,布布扣
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int N=210;
const int INF=0x3f3f3f3f;
int nx,ny;
int linker[N],lx[N],ly[N],slack[N];  
int visx[N],visy[N],w[N][N];
int DFS(int x)
{
    visx[x]=1;
    for(int y=1;y<=ny;y++){
        if(visy[y])
            continue;
        int tmp=lx[x]+ly[y]-w[x][y];
        if(tmp==0){
            visy[y]=1;
            if(linker[y]==-1 || DFS(linker[y])){
                linker[y]=x;
                return 1;
            }
        }else if(slack[y]>tmp){ 
            slack[y]=tmp;
        }
    }
    return 0;
}
int KM()
{
    int i,j;
    memset(linker,-1,sizeof(linker));
    memset(ly,0,sizeof(ly));
    for(i=1;i<=nx;i++)      
        for(j=1,lx[i]=-INF;j<=ny;j++)
            if(w[i][j]>lx[i])
                lx[i]=w[i][j];
    for(int x=1;x<=nx;x++){
        for(i=1;i<=ny;i++)
            slack[i]=INF;
        while(1){
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            if(DFS(x))  
                break;  
            int d=INF;
            for(i=1;i<=ny;i++)
                if(!visy[i] && d>slack[i])
                    d=slack[i];
            for(i=1;i<=nx;i++)
                if(visx[i])
                    lx[i]-=d;
            for(i=1;i<=ny;i++) 
                if(visy[i])
                    ly[i]+=d;
                else
                    slack[i]-=d;
        }
    }
    int res=0;
    for(i=1;i<=ny;i++)
        if(linker[i]!=-1)
            res+=w[linker[i]][i];
    return res;
}
int main()
{
    int n,m,k ;
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        nx=n;ny=m;
        for(int i=0 ;i<N ;i++)
            for(int j=0 ;j<N ;j++)
                w[i][j]=-INF ;
          int p1=1,p2=1 ;
          map <string,int> mp1,mp2 ;
        for(int i=0 ;i<k ;i++)
        {
            char a[205],b[205] ;
            int v ;
            scanf("%s%s%d",a,b,&v) ;
            string s1(a),s2(b) ;
            if(!mp1[s1])mp1[s1]=p1++ ;
            if(!mp2[s2])mp2[s2]=p2++ ;
            w[mp1[s1]][mp2[s2]]=-v ;
        }
        int ans=KM();
        printf("%d\n",-ans);
    }    
    return 0;
}
View Code

 

HDU 2813,布布扣,bubuko.com

HDU 2813

原文:http://www.cnblogs.com/xiaohongmao/p/3785831.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!