zoukankan      html  css  js  c++  java
  • [hdu2255]奔小康赚大钱(二分图最优匹配、KM算法)

    题目大意:求二分图的最优匹配(首先数目最大, 其次权值最大)。

    解题关键:KM算法

    复杂度:$O(n^3)$

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=310;
    const int inf=0x3f3f3f3f;
    int nx,ny;
    int g[N][N];
    int match[N],lx[N],ly[N];//y中各点匹配状态,x,y中的顶点标号
    int slack[N];
    bool visx[N],visy[N];
    
    bool hungry(int x){
        visx[x]=1;
        for(int y=1; y<=ny; y++){
            if(visy[y])continue;
            int tmp=lx[x]+ly[y]-g[x][y];
            if(tmp==0){
                visy[y]=true;
                if(match[y]==-1 ||hungry(match[y])){
                    match[y]=x;
                    return 1;
                }
            }
            else if(slack[y]>tmp) slack[y]=tmp;
        }
        return 0;
    }
    
    int KM(){
        memset(match, -1, sizeof match);
        memset(ly, 0, sizeof ly);
        for(int i=1;i<=nx;i++){
            lx[i]=-inf;
            for(int j=1;j<=ny;j++) lx[i]=max(lx[i],g[i][j]);
        }
        for(int x=1;x<=nx;x++){
            for(int i=1;i<=ny;i++) slack[i]=inf;
            while(1){
                memset(visx,0,sizeof visx);
                memset(visy,0,sizeof visy);
                if(hungry(x))break;
                int d=inf;
                for(int i=1;i<=ny;i++)if(!visy[i]&&d>slack[i]) d=slack[i];
                for(int i=1;i<=nx;i++)if(visx[i])lx[i]-=d;
                for(int i=1;i<=ny;i++){
                    if(visy[i])ly[i]+=d;
                    else slack[i]-=d;
                }
            }
        }
        int res=0;
        for(int i=1;i<=ny;i++)
            if(match[i]!=-1) res+=g[match[i]][i];
        return res;
    }
    
    int main(){
        int n;
        while(~scanf("%d",&n)){
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    scanf("%d",&g[i][j]);
            nx=ny=n;
            printf("%d
    ",KM());
        }
        return 0;
    }
     
  • 相关阅读:
    JDK安装,环境配置
    XSS攻击测试代码
    css3 input边框蓝光特效
    PDFobject插件使用,PDF在线查看插件
    网页中嵌入可以点击“运行代码”执行html/css/js代码
    SmohanTimeLine.js 酷炫的时间轴效果
    java进行文件上传,带进度条
    javascript读取xml文件
    C# 动态类型与动态编译简介
    Mac 命令行美化
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/8975747.html
Copyright © 2011-2022 走看看