zoukankan      html  css  js  c++  java
  • KM算法(二分图最大权匹配)

    #include <bits/stdc++.h>
    #define N 1500
    #define inf 999999999
    using namespace std;
    int a[N],bs[N],nx=0,ny=0,k;
    int linky[N],lx[N],ly[N],slack[N];
    int visx[N],visy[N],w[N][N];
    int min(int a,int b){return (a<b)?a:b;}
    int find(int x){
        visx[x]=1;
        for(int y=1;y<=ny;y++){
            if(visy[y]) continue;
            int t=lx[x]+ly[y]-w[x][y];
            if(t==0){visy[y]=1;
                if(linky[y]==-1||find(linky[y])){
                    linky[y]=x;return 1;
                }
            }
            else if(slack[y]>t) slack[y]=t;
        }
        return 0;
    }
    int km(){
        memset(linky,-1,sizeof(linky));
        memset(ly,0,sizeof(ly));
        for(int i=1;i<=nx;i++) lx[i]=-inf;
        for(int i=1;i<=nx;i++)for(int j=1;j<=ny;j++)if(w[i][j]>lx[i])lx[i]=w[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(find(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 result=0;
        for(int i=1;i<=ny;i++)
        if(linky[i]>-1) result+=w[linky[i]][i];
        return result;
    }
    int main(){
        scanf("%d%d%d",&nx,&ny,&k);
        for(int i=1;i<=k;i++){
            int a,b,c;scanf("%d%d%d",&a,&b,&c);
            w[a][b]=c;
        }printf("%d
    ",km());
        return 0;
    }
    rush!
  • 相关阅读:
    SqlServer 利用临时表批量添加&&修改数据库表中的数据
    有关Linux的实时性
    烟囱式到SOA再到微服务
    消费金融前世今生
    其它 一加7t禁止系统更新
    电商 相关底层知识
    CRMEB 基础 列表拖动排序2
    CRMEB 基础 列表拖动排序1
    前端 table排序
    MacBook 关闭访客登陆
  • 原文地址:https://www.cnblogs.com/LH2000/p/14152226.html
Copyright © 2011-2022 走看看