• HDU 2813


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

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

    #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
    ",-ans);
        }    
        return 0;
    }
    View Code
  • 相关阅读:
    redis的两种备份方式
    Vue—事件修饰符
    css3实现颤动的动画
    初学者可能不知道的vue技巧
    使用slot-scope复制vue中slot内容
    pre-commit钩子,代码质量检查
    爬虫可视化点选配置工具之获取鼠标点选元素
    Vue源码探究-事件系统
    使用electron实现百度网盘悬浮窗口功能!
    electron实现qq快捷登录!
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3785831.html
Copyright © 2020-2023  润新知