zoukankan      html  css  js  c++  java
  • [POJ 2195] Going Home

    [题目链接]

              http://poj.org/problem?id=2195

    [算法]

              KM算法求二分图带权最小匹配
    [代码]

             

    #include <algorithm>  
    #include <bitset>  
    #include <cctype>  
    #include <cerrno>  
    #include <clocale>  
    #include <cmath>  
    #include <complex>  
    #include <cstdio>  
    #include <cstdlib>  
    #include <cstring>  
    #include <ctime>  
    #include <deque>  
    #include <exception>  
    #include <fstream>  
    #include <functional>  
    #include <limits>  
    #include <list>  
    #include <map>  
    #include <iomanip>  
    #include <ios>  
    #include <iosfwd>  
    #include <iostream>  
    #include <istream>  
    #include <ostream>  
    #include <queue>  
    #include <set>  
    #include <sstream>  
    #include <stdexcept>  
    #include <streambuf>  
    #include <string>  
    #include <utility>  
    #include <vector>  
    #include <cwchar>  
    #include <cwctype>  
    #include <stack>  
    #include <limits.h>
    using namespace std;
    #define MAXN 5010
    const int inf = 2e9;
    
    int i,j,l1,l2,n,m,delta;
    int match[MAXN],la[MAXN],lb[MAXN];
    bool visiteda[MAXN],visitedb[MAXN];
    int w[MAXN][MAXN];
    pair<int,int> man[MAXN],house[MAXN];
    char mp[MAXN][MAXN];
    
    inline int dist(pair<int,int> a,pair<int,int> b)
    {
            return abs(a.first - b.first) + abs(a.second - b.second);
    }
    inline bool dfs(int u)
    {
            int v;
            visiteda[u] = true;
            for (v = 1; v <= l1; v++)
            {
                    if (!visitedb[v])
                    {
                            if (la[u] + lb[v] - w[u][v] == 0)
                            {
                                    visitedb[v] = true;
                                    if (!match[v] || dfs(match[v]))
                                    {
                                            match[v] = u;
                                            return true;
                                    }
                            } 
                    }
            }
            return false;
    }
    inline int KM()
    {
            int i,j,k,ret;
            for (i = 1; i <= l1; i++)
            {
                    la[i] = -inf;    
                    lb[i] = 0;
                    match[i] = 0;
                    for (j = 1; j <= l1; j++) la[i] = max(la[i],w[i][j]);    
            }        
            for (i = 1; i <= l1; i++)
            {
                    while (true)
                    {
                            for (j = 1; j <= l1; j++) visiteda[j] = visitedb[j] = false;
                            if (dfs(i)) break;
                            delta = inf;
                            for  (j = 1; j <= l1; j++)
                            {
                                    if (visiteda[j])
                                    {
                                            for (k = 1; k <= l1; k++)
                                            {
                                                    if (!visitedb[k])
                                                            delta = min(delta,la[j] + lb[k] - w[j][k]);
                                            }
                                    }
                            }
                            for (j = 1; j <= l1; j++)
                            {
                                    if (visiteda[j]) la[j] -= delta;
                                    if (visitedb[j]) lb[j] += delta;
                            }
                    }
            }
            ret = 0;
            for (i = 1; i <= l1; i++) ret += w[match[i]][i];
            return ret;
    }
     
    int main() 
    {
            
            while (scanf("%d%d",&n,&m) && (n || m))
            {
                    l1 = l2 = 0;
                    for (i = 1; i <= n; i++) scanf("%s",mp[i] + 1);
                    for (i = 1; i <= n; i++)
                    {
                            for (j = 1; j <= m; j++)
                            {
                                    if (mp[i][j] == 'm') man[++l1] = make_pair(i,j);
                                    if (mp[i][j] == 'H') house[++l2] = make_pair(i,j);
                            }
                    }
                    for (i = 1; i <= l1; i++)
                    {
                            for (j = 1; j <= l1; j++)
                            {
                                    w[i][j] = -dist(man[i],house[j]);
                            }
                    }
                    printf("%d
    ",-KM());
            }
             
            return 0;
        
    }
  • 相关阅读:
    channel 功能解析
    Docker 使用 Jenkins 镜像创建容器(转)
    使用Gson将Object转String出现u003d 的原因
    Gradle基础
    JAVA HashMap 和 HashSet 的区别
    ViewStub基本用法
    String类的内存分配
    区块链--资产数字化之路
    选择排序
    冒泡排序
  • 原文地址:https://www.cnblogs.com/evenbao/p/9437027.html
Copyright © 2011-2022 走看看