zoukankan      html  css  js  c++  java
  • 奔小康赚大钱 hdu 2255( KM )

    http://acm.split.hdu.edu.cn/showproblem.php?pid=2255

    带权匹配问题:

    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    using namespace std;
    
    #define maxn 330
    #define INF 0xfffffff
    
    int maps[maxn][maxn], vx[maxn], vy[maxn], used[maxn], lx[maxn], ly[maxn], s[maxn], n;
    ///vx[i]代表第i人是否在增广路上
    ///used[i]代表第i个村庄是否被占用
    ///lx[],ly[]代表人和村庄的顶标
    
    int Find(int u)
    {
        vx[u] = 1;
    
        for(int i=1; i<=n; i++)
        {
            if(!vy[i] && lx[u]+ly[i] == maps[u][i])
            {
                vy[i] = 1;
    
                if(!used[i] || Find(used[i]))
                {
                    used[i] = u;
                    return 1;
                }
            }
            else
            {
                s[i] = min(s[i], lx[u]+ly[i]-maps[u][i]);
            }
        }
        return 0;
    }
    
    int KM()
    {
        memset(used, 0, sizeof(used));
        memset(lx, 0, sizeof(lx));
        memset(ly, 0, sizeof(ly));
    
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                lx[i] = max(maps[i][j], lx[i]);///初始化人的顶标
    
        for(int i=1; i<=n; i++)///寻找最大匹配
        {
            for(int j=1; j<=n; j++)
                s[j] = INF;
    
            while(1)
            {
                memset(vx, 0, sizeof(vx));
                memset(vy, 0, sizeof(vy));
    
                if(Find(i))  break;///找到增广路就退出,否则改变顶标,直到找到为止
    
                int d = INF;
    
                for(int j=1; j<=n; j++)
                {
                    if(!vy[j]) d=min(d, s[j]);
                }
    
                for(int j=1; j<=n; j++)
                {
                    if(vx[j]) lx[j] -= d;
                    if(vy[j]) ly[j] += d;
                }
            }
        }
    
        int ans = 0;
    
        for(int i=1; i<=n; i++)
            ans += maps[used[i]][i];
    
        return ans;
    }
    
    int main()
    {
        while(scanf("%d", &n)!=EOF)
        {
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    scanf("%d", &maps[i][j]);
    
            printf("%d
    ", KM());
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HTTP Status 401
    Spring Data Elasticsearch 应用
    Elasticsearch基础概念
    Windows上使用Linux命令
    在服务器搭建git仓库
    SSH
    Linux/Windows 配置config 使用ssh连接
    在阿里云CentOS服务器上安装Python3.7并设置为默认Python
    Linux下Python3源码安装
    Vue
  • 原文地址:https://www.cnblogs.com/daydayupacm/p/5795879.html
Copyright © 2011-2022 走看看