• POJ2195Going Home【KM】


    题意:

    给一个矩阵,m代表人H代表房子,现在想让人移动最少的步数回到房子中

    分析:

    可用二分图和网络流来写

    二分图:X集合为人Y集合为房子,人与每个房子的连一条边为-dist的边即可,求出最大权值,然后取反即可

    网络流:用费用流来做,人与房子之间建立容量为1,费用为dist的边,求出最小费用即可

    由于人与每个房子之间有有边,所以我用的邻接矩阵处理的

    二分图代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <map>
      5 #include <vector>
      6 #include <cmath>
      7 using namespace std;
      8 
      9 const int maxn = 105;
     10 const int INF = 1000000000;
     11 
     12 typedef pair<int, int> PII;
     13 vector<PII> v[2];
     14 
     15 
     16 int n_cnt;
     17 int W[maxn][maxn];
     18 int Lx[maxn], Ly[maxn];
     19 int Left[maxn];
     20 bool S[maxn], T[maxn];
     21 
     22 bool match(int i) {
     23     S[i] = true;
     24     for(int j = 1; j <= n_cnt; j++) if(Lx[i] + Ly[j] == W[i][j] && !T[j]) {
     25         T[j] = true;
     26         if(!Left[j] || match(Left[j])) {
     27             Left[j] = i;
     28             return true;
     29         }
     30     }
     31     return false;
     32 }
     33 
     34 
     35 void update() {
     36     int a = INF;
     37     for(int i = 1; i <= n_cnt; i++) if(S[i]) {
     38         for(int j = 1; j <= n_cnt; j++) if(!T[j]) {
     39             a = min(a, Lx[i] + Ly[j] - W[i][j]);
     40         }
     41     }
     42     for(int i = 1; i <= n_cnt; i++) {
     43         if(S[i]) Lx[i] -= a;
     44         if(T[i]) Ly[i] += a;
     45     }
     46 }
     47 
     48 void KM() {
     49     for(int i = 1; i <= n_cnt; i++) {
     50         Left[i] = Lx[i] = Ly[i] = 0;
     51         for(int j = 1; j <= n_cnt; j++) {
     52             Lx[i] = max(Lx[i], W[i][j]);
     53         }
     54     }
     55     for(int i = 1; i <= n_cnt; i++) {
     56         for(;;) {
     57             for(int j = 1; j <= n_cnt; j++) S[j] = T[j] = 0;
     58             if(match(i)) break;
     59             else update();
     60         }
     61     }
     62 }
     63 
     64 int dist(PII p1, PII p2) {
     65     return fabs(p1.first - p2.first) + fabs(p1.second - p2.second);
     66 }
     67 
     68 int main() {
     69     int n, m;
     70 //    freopen("a.txt","r",stdin);
     71     while(scanf("%d %d",&n, &m) && n + m) {
     72         char mat[maxn][maxn];
     73         memset(W, 0, sizeof(W));
     74         v[0].clear(); v[1].clear();
     75         for(int i = 0; i < n; i++) {
     76                 scanf("
    %s",mat[i]);
     77                // puts(mat[i]);
     78         }
     79         for(int i = 0; i < n; i++) {
     80             for(int j = 0; j < m; j++) {
     81                 if(mat[i][j] == 'm')
     82                     v[0].push_back(make_pair(i, j));
     83                 else if(mat[i][j] == 'H')
     84                     v[1].push_back(make_pair(i, j));
     85             }
     86         }
     87         n_cnt = v[0].size();
     88 //        printf("n == %d
    ",n_cnt);
     89         for(int i = 0; i < n_cnt; i++) {
     90             for(int j = 0; j < n_cnt; j++) {
     91                 W[i + 1][j + 1] = -dist(v[0][i], v[1][j]);
     92             }
     93         }
     94         KM();
     95         int ans = 0;
     96         for(int i = 1; i <= n_cnt; i++) {
     97             ans += Lx[i] + Ly[i];
     98         }
     99         printf("%d
    ",-ans);
    100     }
    101     return 0;
    102 }
    View Code
    
    
  • 相关阅读:
    【Silverlight】Bing Maps系列文章汇总
    《MEF程序设计指南》博文汇总
    Flash中各种图形的绘制
    Bing Maps开发扩展二:基于Oracle Spatial的空间数据分析
    Bing Maps开发扩展三:Bing Maps中渲染ESRI SHP空间数据
    Spring Cloud Gateway
    Spring Cloud Gateway 整合 nacos
    Spring Cloud Gateway 断言(Predicate) (hoxton 版本)
    Python和Node.js支持尾递归吗?
    用OpenCv来做人脸识别
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3895930.html
Copyright © 2020-2023  润新知