zoukankan      html  css  js  c++  java
  • HDU-1533 Going Home

    Going Home

    题意:给你一张图,图上有若干个人和若干个屋子,现在要使的这若干个人都进到屋子里,并且一个屋子只能进一个人,求总步数最小。

    题解:最小费用流。将图转化成边的关系,然后求解。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 
     14 typedef pair<int,int> pll;
     15 const int INF = 0x3f3f3f3f;
     16 const LL mod =  (int)1e9+7;
     17 const int N = 50005;
     18 char str[205][205];
     19 int px[N], py[N];
     20 int head[N], to[N], ct[N], w[N], nt[N];
     21 int d[N], vis[N];
     22 int pre[N], id[N];
     23 int n, m, s, t, tot;
     24 
     25 void add(int u, int v, int val, int cost){
     26     to[tot] = v;
     27     ct[tot] = cost;
     28     w[tot] = val;
     29     nt[tot] = head[u];
     30     head[u] = tot++;
     31 }
     32 
     33 void get_G(){
     34     int p = 0, z = 0;
     35     s = 0;
     36     for(int i = 1; i <= n; i++)
     37         for(int j = 1; j <= m; j++)
     38             if(str[i][j] == 'H'){
     39                 ++p;
     40                 px[p] = i;
     41                 py[p] = j;
     42             }
     43     for(int i = 1; i <= n; i++)
     44         for(int j = 1; j <= m; j++)
     45             if(str[i][j] == 'm'){
     46                 z++;
     47                 add(s,z+p,1,0);
     48                 add(z+p,s,0,0);
     49                 for(int k = 1; k <= p; k++){
     50                     add(z+p,k,1,abs(i-px[k])+abs(j-py[k]));
     51                     add(k,z+p,0,-(abs(i-px[k])+abs(j-py[k])));
     52                 }
     53             }
     54     t = p + z + 1;
     55     for(int i = 1; i <= p; i++){
     56         add(i,t,1,0);
     57         add(t,i,0,0);
     58     }
     59 }
     60 void init(){
     61     memset(head,-1,sizeof(head));
     62     tot = 0;
     63 }
     64 
     65 int spfa(){
     66     queue<int> q;
     67     memset(d, INF, sizeof(d));
     68     memset(vis, 0, sizeof(vis));
     69     memset(pre, -1, sizeof(vis));
     70     d[s] = 0;
     71     q.push(s);
     72     while(!q.empty()){
     73         int u = q.front(); q.pop();
     74         vis[u] = 0;
     75         for(int i = head[u]; ~i; i = nt[i]){
     76             if(w[i] > 0 && d[to[i]] > d[u] + ct[i]){
     77                 d[to[i]] = d[u] + ct[i];
     78                 pre[to[i]] = u;
     79                 id[to[i]] = i;
     80                 if(!vis[to[i]]){
     81                     vis[to[i]] = 1;
     82                     q.push(to[i]);
     83                 }
     84             }
     85         }
     86 
     87     }
     88     return d[t] < INF;
     89 }
     90 
     91 int MaxFlow(){
     92     int Mi = INF;
     93     int sum = 0;
     94     while(spfa()){
     95         Mi = INF;
     96         for(int i = t; i != s; i = pre[i])
     97             Mi = min(Mi, w[id[i]]);
     98         for(int i = t; i != s; i = pre[i]){
     99             w[id[i]] -= Mi;
    100             w[id[i]^1] += Mi;
    101         }
    102         sum += d[t];
    103     }
    104     return sum;
    105 }
    106 
    107 int main(){
    108     while(~scanf("%d%d", &n, &m), n+m){
    109         init();
    110         for(int i = 1; i <= n; i++)
    111             scanf("%s", str[i]+1);
    112         get_G();
    113         printf("%d
    ", MaxFlow());
    114     }
    115     return 0;
    116 }
    KM 费用流

    第一次写KM费用流,跑的特别慢,希望下次能改进。

  • 相关阅读:
    MySQL 删除有外键约束的表数据
    Python 类装饰器解析
    保持SSH连接的linux服务器不断线
    数字货币交易所常用概念
    Python f-string
    Linux sed命令
    CAS机制详解
    MySQL缓存机制
    PHP网络请求优化
    Java三大特性---继承
  • 原文地址:https://www.cnblogs.com/MingSD/p/9303369.html
Copyright © 2011-2022 走看看