• Going Home HDU-1533(费用流)


    题意:

    一个$N$行$M$列的矩阵,其中$"."$代表空地,$"H"$代表房子,$"m"$代表人,其中有$n$个房子和$n$个人。现在要求每个人进入其中的一间房子,且每人每走一步需要支付$1$美元。求最小需要花费多少美元能让所有人都进入到房子中(每个人只能进入一间房子,每个房子只能容纳一个人)。

    思路:

    费用流,人和源点建流量$1$费用$0$的边;人和房子建流量$1$,费用为哈夫曼距离的边;房子和汇点建流量$1$费用$0$的边。

    代码:

      1 //#include<bits/stdc++.h>
      2 #include <set>
      3 #include <map>
      4 #include <stack>
      5 #include <cmath>
      6 #include <queue>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstring>
     11 #include <iostream>
     12 #include <algorithm>
     13 
     14 #define ll long long
     15 #define pll pair<ll,ll>
     16 #define pii pair<int,int>
     17 #define bug printf("*********
    ")
     18 #define FIN freopen("input.txt","r",stdin);
     19 #define FON freopen("output.txt","w+",stdout);
     20 #define IO ios::sync_with_stdio(false),cin.tie(0)
     21 #define ls root<<1
     22 #define rs root<<1|1
     23 #define Q(a) cout<<a<<endl
     24 
     25 using namespace std;
     26 const int inf = 0x3f3f3f3f;
     27 const ll Inf = 1e18 + 7;
     28 const int maxn = 1e4 + 5;
     29 const int mod = 1e9 + 7;
     30 
     31 ll gcd(ll a, ll b)
     32 {
     33     return b ? gcd(b, a % b) : a;
     34 }
     35 
     36 ll lcm(ll a, ll b)
     37 {
     38     return a / gcd(a, b) * b;
     39 }
     40 
     41 ll read()
     42 {
     43     ll p = 0, sum = 0;
     44     char ch;
     45     ch = getchar();
     46     while (1)
     47     {
     48         if (ch == '-' || (ch >= '0' && ch <= '9'))
     49             break;
     50         ch = getchar();
     51     }
     52 
     53     if (ch == '-')
     54     {
     55         p = 1;
     56         ch = getchar();
     57     }
     58     while (ch >= '0' && ch <= '9')
     59     {
     60         sum = sum * 10 + ch - '0';
     61         ch = getchar();
     62     }
     63     return p ? -sum : sum;
     64 }
     65 
     66 struct Dinic
     67 {
     68     int head[maxn], tot, cur[maxn];
     69     int dis[maxn];
     70     int s, e;
     71     queue<int>q;
     72 
     73     struct node
     74     {
     75         int v, w;
     76         int next;
     77     }p[maxn];
     78 
     79     void init()
     80     {
     81         tot = 0;
     82         memset(head, -1, sizeof head);
     83     }
     84 
     85     void add(int u, int v, int w)
     86     {
     87         p[tot].v = v;
     88         p[tot].w = w;
     89         p[tot].next = head[u];
     90         head[u] = tot++;
     91     }
     92 
     93     void addEdge(int u, int v, int w)
     94     {
     95         add(u, v, w);
     96         add(v, u, 0);
     97     }
     98 
     99     bool bfs()
    100     {
    101         memset(dis, 0, sizeof dis);
    102         while (!q.empty())   q.pop();
    103         dis[s] = 1;
    104         q.push(s);
    105         while (!q.empty())
    106         {
    107             int x = q.front();
    108             q.pop();
    109             for (int i = head[x]; i != -1; i = p[i].next)
    110             {
    111                 int v = p[i].v, w = p[i].w;
    112                 if (!dis[v] && w)
    113                 {
    114                     dis[v] = dis[x] + 1;
    115                     q.push(v);
    116                 }
    117             }
    118         }
    119         if (dis[e])  return true;
    120         return false;
    121     }
    122 
    123     int dfs(int x, int W)
    124     {
    125         if (x == e || W == 0)  return W;
    126         int res = 0;
    127         for (int i = cur[x]; i != -1; i = p[i].next)
    128         {
    129             cur[x] = p[i].next;
    130             int v = p[i].v, w = p[i].w;
    131             if (dis[v] == dis[x] + 1)
    132             {
    133                 int f = dfs(v, min(w, W));
    134                 p[i].w -= f;
    135                 p[i ^ 1].w += f;
    136                 W -= f;
    137                 res += f;
    138                 if (W == 0)    break;
    139             }
    140         }
    141         return res;
    142     }
    143 
    144     int getMaxFlow()
    145     {
    146         int ans = 0;
    147         while (bfs())
    148         {
    149             for (int i = s; i <= e; ++i) cur[i] = head[i];
    150             ans += dfs(s, inf);
    151         }
    152         return ans;
    153     }
    154 }DC;
    155 
    156 struct stortest_Floyd {
    157     int a[5000][5000];
    158     void floyd(int num) {
    159         for (int k = 1; k <= num; k++) {
    160             for (int i = 1; i <= num; i++) {
    161                 for (int j = 1; j <= num; j++) {
    162                     if (a[i][j] > a[i][k] + a[k][j]) {
    163                         a[i][j] = a[i][k] + a[k][j];
    164                     }
    165                 }
    166             }
    167         }
    168     }
    169 }Floyd;
    170 
    171 struct Min_Cost_Max_Flow
    172 {
    173     struct Edge
    174     {
    175         int from, to, cap, flow, cost;
    176     };
    177     
    178     vector<Edge>edges;
    179     vector<int>G[maxn];
    180     bool vis[maxn];
    181     int d[maxn], p[maxn], a[maxn];
    182     int n, m, s, t;
    183     
    184     void init(int n, int s, int t)
    185     {
    186         this->n = n, this->s = s, this->t = t;
    187         for (int i = 1; i <= n; ++i)
    188         {
    189             G[i].clear();
    190         }
    191         edges.clear();
    192     }
    193     
    194     void add_edge(int from, int to, int cap, int cost)
    195     {
    196         edges.push_back({ from,to,cap,0,cost });
    197         edges.push_back({ to,from,0,0,-cost });
    198         m = edges.size();
    199         G[from].push_back(m - 2);
    200         G[to].push_back(m - 1);
    201     }
    202 
    203     bool SPFA(int& flow, int& cost)
    204     {
    205         memset(d, inf, sizeof d);
    206         memset(vis, false, sizeof vis);
    207         memset(p, -1, sizeof p);
    208         d[s] = 0, vis[s] = true, p[s] = 0, a[s] = inf;
    209 
    210         std::queue<int>que;
    211         que.push(s);
    212         while (!que.empty())
    213         {
    214             int u = que.front();
    215             que.pop();
    216             vis[u] = false;
    217             for (int i = 0; i < G[u].size(); ++i)
    218             {
    219                 Edge& e = edges[G[u][i]];
    220                 if (e.cap > e.flow&& d[e.to] > d[u] + e.cost)
    221                 {
    222                     d[e.to] = d[u] + e.cost;
    223                     p[e.to] = G[u][i];
    224                     a[e.to] = std::min(a[u], e.cap - e.flow);
    225                     if (!vis[e.to])
    226                     {
    227                         vis[e.to] = true;
    228                         que.push(e.to);
    229                     }
    230                 }
    231             }
    232         }
    233 
    234         if (d[t] == inf)   return false;
    235         flow += a[t];
    236         cost += d[t] * a[t];
    237         int u = t;
    238         while (u != s)
    239         {
    240             edges[p[u]].flow += a[t];
    241             edges[p[u] ^ 1].flow -= a[t];
    242             u = edges[p[u]].from;
    243         }
    244         return true;
    245     }
    246 
    247     void solve(int& flow, int& cost)
    248     {
    249         flow = cost = 0;
    250         while (SPFA(flow, cost));
    251     }
    252 };
    253 
    254 char s[maxn][maxn];
    255 vector<pii>house, man;
    256 
    257 int main()
    258 {
    259     int n, m;
    260     while (~scanf("%d %d", &n, &m))
    261     {
    262         if (n + m == 0)  break;
    263         house.clear(), man.clear();
    264         for (int i = 1; i <= n; ++i)
    265         {
    266             scanf("%s", s[i] + 1);
    267             for (int j = 1; j <= m; ++j)
    268             {
    269                 if (s[i][j] == 'H')
    270                     house.push_back({ i,j });
    271                 else if (s[i][j] == 'm')
    272                     man.push_back({ i,j });
    273             }
    274         }
    275 
    276         int sz1 = man.size(), sz2 = house.size();
    277         int st = 0, ed = sz1 + sz2 + 1;
    278         Min_Cost_Max_Flow mcmf;
    279         mcmf.init(ed + 1, st, ed);
    280         for (int i = 0; i < sz1; ++i)
    281         {
    282             mcmf.add_edge(st, i + 1, 1, 0);
    283             int x1 = man[i].first, y1 = man[i].second;
    284             for (int j = 0; j < sz2; ++j)
    285             {
    286                 int x2 = house[j].first, y2 = house[j].second;
    287                 mcmf.add_edge(i + 1, sz1 + j + 1, 1, abs(x1 - x2) + abs(y1 - y2));
    288             }
    289         }
    290         for (int i = 0; i < sz2; ++i)
    291             mcmf.add_edge(i + sz1 + 1, ed, 1, 0);
    292         int flow, cost;
    293         mcmf.solve(flow, cost);
    294         cout << cost << endl;
    295     }
    296 }

     

  • 相关阅读:
    4G DTU是什么 4G DTU有什么功能
    模拟量转485采集模块是什么
    vue详情页回到列表页定位到之前位置(keep-alive)
    vue插槽
    elementUI给table表头加CheckBox
    $attrs和$listeners
    parseTime-格式化时间
    localStorage设置过期时间
    前端埋点
    将接口数据通过递归过滤
  • 原文地址:https://www.cnblogs.com/zhang-Kelly/p/12593620.html
Copyright © 2020-2023  润新知