题目链接:https://vjudge.net/problem/POJ-2195

思路:曼哈顿距离来求每个人到每个房间的距离,把距离当作费用。

就可以用最小费用最大流来解决了,把每个房子拆成两个点,限流。

源点->人->房入->房出->汇点。流量的话都设置为1,起到限流作用。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std; const int N = ,INF = (int)1e9;
int n,m,tot,num;
int head[N<<],d[N<<],vis[N<<],pre[N<<];
char mp[N][N];
vector<pair<int,int > > p;
vector<pair<int,int > > h;
struct node{
int to,nxt,cap,flow,cost;
}e[N*N]; void show(){
cout << endl;
for(int i = ; i < n; ++i) cout << mp[i] << endl;
for(int i = ; i < num; ++i) printf("( %d, %d) ",p[i].first,p[i].second);
cout << endl;
for(int i = ; i < num; ++i) printf("( %d, %d) ",h[i].first,h[i].second);
cout << endl << endl;
}
//求距离
inline int _dis(int x,int y){
return abs(p[x].first - h[y].first) + abs(p[x].second - h[y].second);
} inline void add(int u,int v,int cap,int flow,int cost){
e[tot].to = v;
e[tot].cap = cap;
e[tot].flow = flow;
e[tot].cost = cost;
e[tot].nxt = head[u];
head[u] = tot++;
e[tot].to = u;
e[tot].cap = ;
e[tot].flow = flow;
e[tot].cost = -cost;
e[tot].nxt = head[v];
head[v] = tot++;
} void build_map(int s,int t){ //0源点 1~num人 num+1~2*num 房入 2*num+1~3*num房出 3*num+1汇点
int cost;
for(int i = ; i < num; ++i){
for(int j = ; j < num; ++j){
cost = _dis(i,j);
add(i+,j++num,,,cost);
}
}
for(int i = ; i < num; ++i) add(s,i+,,,);
for(int i = ; i < num; ++i) add(i++num,i++*num,,,);
for(int i = ; i < num; ++i) add(i++*num,t,,,);
} bool spfa(int s,int t){
for(int i = s; i <= t; ++i) pre[i] = -;
for(int i = s; i <= t; ++i) d[i] = INF; d[s] = ;
for(int i = s; i <= t; ++i) vis[i] = false; vis[s] = true;
queue<int > que;
que.push(s);
while(!que.empty()){
int now = que.front(); que.pop();
vis[now] = false;
for(int o = head[now]; ~o; o = e[o].nxt){
int to = e[o].to;
if(e[o].cap > e[o].flow && d[to] > d[now] + e[o].cost){
d[to] = d[now] + e[o].cost;
pre[to] = o;
if(!vis[to])
vis[to] = true;
que.push(to);
}
}
}
if(pre[t] == -) return false;
else return true;
} int work(){ int s = ,t = *num+,ans = ;
for(int i = s; i <= t; ++i) head[i] = -; tot = ;
build_map(s,t);
while(spfa(s,t)){
int Min = INF;
for(int o = pre[t]; ~o; o = pre[e[o^].to]){
Min = min(Min,e[o].cap - e[o].flow);
}
for(int o = pre[t]; ~o; o = pre[e[o^].to]){
e[o].flow += Min;
e[o^].flow -= Min;
}
ans += Min*d[t];
}
return ans;
} int main(){ while(~scanf("%d%d",&n,&m) && (n+m)){
for(int i = ; i < n; ++i) scanf("%s",mp[i]);
p.clear(); h.clear();
for(int i = ; i < n; ++i){
for(int j = ; j < m; ++j){
if(mp[i][j] == 'm') p.push_back(make_pair(i,j));
if(mp[i][j] == 'H') h.push_back(make_pair(i,j));
}
}
num = p.size();
//show();
//cout << "------------------------------------" << work() << endl;
cout << work() << endl;
} return ;
}

kuangbin专题专题十一 网络流 Going Home POJ - 2195的更多相关文章

  1. kuangbin专题专题十一 网络流 Minimum Cost POJ - 2516

    题目链接:https://vjudge.net/problem/POJ-2516 思路:对于每种商品跑最小费用最大流,如果所有商品和人一起建图跑,O(v^2*m)数量级太大,会超时. 把店里的商品拆点 ...

  2. 图论--网络流--费用流POJ 2195 Going Home

    Description On a grid map there are n little men and n houses. In each unit time, every little man c ...

  3. [kuangbin带你飞]专题十一 网络流

            ID Origin Title   34 / 81 Problem A POJ 3436 ACM Computer Factory   92 / 195 Problem B POJ 3 ...

  4. Kuangbin 带你飞专题十一 网络流题解 及模版 及上下界网络流等问题

    首先是几份模版 最大流:虽然EK很慢但是优势就是短.求最小割的时候可以根据增广时的a数组来判断哪些边是割边.然而SAP的最大流版我只会套版,并不知道该如何找到这个割边.在尝试的时候发现了一些问题.所以 ...

  5. POJ 2195 Going Home 最小费用最大流 尼玛,心累

    D - Going Home Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  6. poj 2195 二分图带权匹配+最小费用最大流

    题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...

  7. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

  8. POJ 2195 Going Home (带权二分图匹配)

    POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...

  9. poj 2195 Going Home(最小费最大流)

    poj 2195 Going Home Description On a grid map there are n little men and n houses. In each unit time ...

随机推荐

  1. Java实现简单的学生成绩管理系统

    ScoreInformation.java import java.util.Scanner; class ScoreInformation {    private String stunumber ...

  2. Android5_浅谈Java的package机制

    当代码量越来越大,类越来越多.尤其会增加同名类的风险.所以对类进行管理就显得非常重要. 包(package)机制是java中管理类的重要手段. 包名的命名方式:业内默认的做法是使用公司的网络域名的倒写 ...

  3. VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti

    出现问题的原因: 原因一.出现此问题的原因是Device Guard或Credential Guard与Workstation不兼容. 原因二.Windows系统的Hyper-V不兼容导致. 解决方案 ...

  4. 自荐一个 element 表单代码生成器

    Element UI 表单设计及代码生成器,可将生成的代码直接运行在基于 Element 的 vue 项目中. github仓库   https://github.com/JakHuang/form- ...

  5. #ICCV2019论文阅读#Fully_convolutional_Features

    一 知识背景 3D scan&cloud points(点云)patch-based features,fully convolutional network, deep metric lea ...

  6. 18.Python模块包(pycharm右键创建文件夹和python package的区别)中__init__.py文件的作用

    原来在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了.当 ...

  7. 【Spark 内核】 Spark 内核解析-上

    Spark内核泛指Spark的核心运行机制,包括Spark核心组件的运行机制.Spark任务调度机制.Spark内存管理机制.Spark核心功能的运行原理等,熟练掌握Spark内核原理,能够帮助我们更 ...

  8. three.js入门第一个案例

    准备工作 1.运用three.js进行3d开发,其实和页面编程一样,首先需要在html文件中引入three.js.Three.js使用面向对象的方式来构建程序,它包含3个基本对象: 场景(scene) ...

  9. Scala实践3

    一.函数式对象 1.1  rational类的规格和创建 Rational类来源于有理数(rational number),来表示n(分子)/d(分母)的数字,同时对有理数的运算(加减乘除)建模,还具 ...

  10. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...