zoukankan      html  css  js  c++  java
  • Ek算法浅析(带权二分图)

    https://www.cnblogs.com/logosG/p/logos.html

    https://blog.csdn.net/chenshibo17/article/details/79933191

    HDU 2255

    /*
     * @Author: CY__HHH
     * @Date: 2019-10-23 20:09:44
     * @LastEditTime: 2019-10-24 16:41:12
     */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<cstring>
    #define inf (0x3f3f3f3f)
    const int maxn = 305;
    int Grape[maxn][maxn];
    int exp_girl[maxn];
    int exp_boys[maxn];
    bool vis_girl[maxn],vis_boys[maxn];
    int match[maxn],minExp[maxn],n;
    using namespace std;
    bool find(int u)
    {
        vis_girl[u] = true;
        for(int v=0;v!=n;++v)
        {
            if(vis_boys[v])
                continue;//只能匹配一次
            int value = exp_girl[u] + exp_boys[v] - Grape[u][v];
            if(!value)//符合要求
            {
                vis_boys[v] = true;//路径
                if(match[v]==-1||find(match[v]))
                {
                    match[v] = u;
                    return true;
                }
            }else{
                minExp[v] = min(minExp[v],value);//得到路径中的左边节点的min
            }
        }
        return false;
    }
    int KM()
    {
        memset(match,-1,sizeof(match));
        memset(exp_boys,0,sizeof(exp_boys));
        for(int v=0;v!=n;++v)
        {
            exp_girl[v] = Grape[v][0];
            for(int i=1;i!=n;++i)
                exp_girl[v] = max(exp_girl[v],Grape[v][i]);
        }//最大期望值
        for(int v=0;v!=n;++v)//为每个girl节点
        {
            memset(minExp,inf,sizeof(minExp));//减少最少权值能够增加边(增广路)
            while(true)//如果找不到,就降低权值
            {
                memset(vis_girl,false,sizeof(vis_girl));
                memset(vis_boys,false,sizeof(vis_boys));//记录路径
                if(find(v))
                    break;//如果找到匹配
                int mind = inf;
                //因为现存的路径中无法满足匹配,所以需要从非路径中节点挑选一个减少最小的来完成(增加边)
                for(int i=0;i!=n;++i)
                    if(!vis_boys[i])
                        mind = min(mind,minExp[i]);
                for(int i=0;i!=n;++i)
                {
                    if(vis_girl[i])
                        exp_girl[i] -= mind;
                    if(vis_boys[i])
                        exp_boys[i] += mind;
                    else
                        minExp[i] -= mind;
                }
            }
        }
        int cnt = 0;
        for(int i=0;i!=n;++i)
            cnt += Grape[match[i]][i];
        return cnt;
    }
    int main()
    {
        while(scanf("%d",&n)==1)
        {
            for(int i=0;i!=n;++i)
                for(int j=0;j!=n;++j)
                    scanf("%d",&Grape[i][j]);
            printf("%d
    ",KM());
        }
    }
    

      

  • 相关阅读:
    德国闪电战和苏联大纵深,谁更厉害?(一个是为了避免战略上的持久战,一个是为了战役的突破)
    “MEAN”技术栈开发web应用
    MVC 01
    适配器模式
    w3wp占用CPU过高
    安装tensorflow
    MemCache分布式内存对象缓存系统
    MVC 使用IBatis.net
    分布式计算
    Remote Desktop Connection Manager
  • 原文地址:https://www.cnblogs.com/newstartCY/p/11733169.html
Copyright © 2011-2022 走看看