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

    代码

    //首先init,传进去的参数分别是两边的点的个数,然后调用solve,如果是求
    //最小值,改为负数,相当于的求负数的最大值。
    struct KM
    {
        int W[maxn][maxn],n,m;
        int Lx[maxn],Ly[maxn];
        int To[maxn];
        bool S[maxn],T[maxn];
        void init(int nn,int mm)
        {
            n=nn; m=mm;
            memset(To,-1,sizeof(To));
            for(int i=1;i<=n;i++) //下标要从1开始
            {
                Lx[i]=Ly[i]=0;
                for(int j=1;j<=m;j++) Lx[i]=max(Lx[i],W[i][j]);
            }
        }
        bool Match(int u)
        {
            S[u]=true;
            for(int v=1;v<=m;v++)
                if(Lx[u]+Ly[v]==W[u][v]&&!T[v])
            {
                T[v]=true;
                if(To[v]==-1||Match(To[v]))
                {
                    To[v]=u;
                    return true;
                }
            }
            return false;
        }
        void Update()
        {
            int a=INF;
            for(int i=1;i<=n;i++)
            {
                if(!S[i]) continue;
                for(int j=1;j<=m;j++)
                    if(!T[j]) a=min(a,Lx[i]+Ly[j]-W[i][j]);
            }
            for(int i=1;i<=n;i++) if(S[i]) Lx[i]-=a;
            for(int i=1;i<=m;i++) if(T[i]) Ly[i]+=a;
        }
        int solve()
        {
            for(int i=1;i<=n;i++)
            {
                while(true)
                {
                    for(int j=1;j<=m;j++) S[j]=T[j]=0;
                    if(Match(i)) break;
                    Update();
                }
            }
            int ret=0;
            for(int i=1;i<=m;i++)
                if(To[i]!=-1) ret+=W[To[i]][i];
            return ret;
        }
    }km;
    View Code
  • 相关阅读:
    demo_10_02 云数据库聚合_bucket_02 bucketAuto
    demo_10_02 云数据库聚合_bucket_01
    nginx 启动脚本
    grep 全局搜索打印命令
    ulimit shell启动进程所占用的资源命令
    nginx 一键安装
    安装 nginx
    学习笔记::杜教筛
    markdown测试
    bzoj4589
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5794865.html
Copyright © 2011-2022 走看看