zoukankan      html  css  js  c++  java
  • 模板 KM算法

    KM算法计算带权二分图最优匹配
    时间复杂度(O(n^3))
    模板题:hdu2255 奔小康赚大钱

    const int maxn=310;
    const int inf=0x3f3f3f3f;
    
    int n;
    int g[maxn][maxn],ex1[maxn],ex2[maxn],match[maxn],slack[maxn];    
    bool vis1[maxn],vis2[maxn];
    
    bool dfs(int x){
        vis1[x]=true;
        for(int y=0;y<n;y++) {
            if(vis2[y]) continue; 
            int gap=ex1[x]+ex2[y]-g[x][y];
            if(gap==0){  
                vis2[y]=true;
                if(match[y]==-1 || dfs(match[y])){   
                    match[y]=x;
                    return true;
                }
            } 
            else{
                slack[y]=min(slack[y],gap);  
            }
        }
        return false;
    }
    
    int KM(){
        memset(match,-1,sizeof(match));    
        memset(ex2,0,sizeof(ex2));  
        for(int i=0;i<n;i++){
            ex1[i]=g[i][0];
            for(int j=0;j<n;j++){
                ex1[i]=max(ex1[i],g[i][j]);
            }
        }
        for(int i=0;i<n;i++){
            memset(slack,0x3f,sizeof(slack));    
            while(1){
                memset(vis1,false,sizeof(vis1));
                memset(vis2,false,sizeof(vis2));
                if(dfs(i)) break;
                int d=inf;
                for(int j=0;j<n;j++)
                    if(!vis2[j]) d=min(d,slack[j]);
                for(int j=0;j<n;j++){
                    if(vis1[j]) ex1[j]-=d;
                    if(vis2[j]) ex2[j]+=d;
                    else slack[j]-=d;
                }
            }
        }
        int res=0;
        for(int i=0;i<n;i++)
            res+=g[match[i]][i];
        return res;
    }
    
  • 相关阅读:
    Win10 蓝屏
    XE Button Color
    IOS 屏幕尺寸
    Delphi 转圈 原型进度条 AniIndicator 及线程配合使用
    Delphi 询问框 汉化
    Delphi Android 询问框
    Delphi BLE 控件
    浮点高低位赋值
    delphi 蓝牙 TBluetoothLE
    16进制字节转换
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13950005.html
Copyright © 2011-2022 走看看