题意:给你一张图,有k个人和k个房子,每个房子只能住一个人,每个人到某一房子的花费为曼哈顿距离,问你让k个人怎么走,使他们都住房子且花费最小。

思路:我们把所有人和超级源点相连,流量为1花费为0,所有房子和超级汇点相连,流量为1花费为0,然后把所有人和所有房子加边,流量为1,花费为曼哈顿距离,这样这道题目就变成了求超级源点到超级汇点的MCMF。

代码:

#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define ll long long
const int maxn = 10000+5;
const int maxm = 100000+5;
const int MOD = 1e7;
const int INF = 1 << 25;
using namespace std;
struct Edge{int to,next,cap,flow,cost;
}edge[maxm];
struct node{int x,y;
}house[maxn],man[maxn];
int head[maxn],tot;
int pre[maxn],dis[maxn];
bool vis[maxn];
int N,M;
void init(){N = maxn;tot = 0;memset(head,-1,sizeof(head));
}
void addEdge(int u,int v,int cap,int cost){edge[tot].to = v;edge[tot].cap = cap;    //容量edge[tot].flow = 0;edge[tot].cost = cost;edge[tot].next = head[u];head[u] = tot++;edge[tot].to = u;edge[tot].cap = 0;edge[tot].flow = 0;edge[tot].cost = -cost;edge[tot].next = head[v];head[v] = tot++;
}
bool spfa(int s,int t){queue<int> q;for(int i = 0;i < N;i++){dis[i] = INF;vis[i] = false;pre[i] = -1;}dis[s] = 0;vis[s] = true;q.push(s);while(!q.empty()){int u = q.front();q.pop();vis[u] = false;for(int i = head[u];i != -1;i = edge[i].next){int v = edge[i].to;if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost){dis[v] = dis[u] + edge[i].cost;pre[v] = i;if(!vis[v]){vis[v] = true;q.push(v);}}}}return pre[t] != -1;
}int MCMF(int s,int t,int &cost){int flow = 0;cost = 0;while(spfa(s,t)){int MIN = INF;for(int i = pre[t];i != -1;i = pre[edge[i^1].to]){if(MIN > edge[i].cap - edge[i].flow){MIN = edge[i].cap - edge[i].flow;}}for(int i = pre[t];i != -1; i = pre[edge[i^1]. to]){edge[i]. flow += MIN;edge[i^1]. flow -= MIN;cost += edge[i]. cost * MIN;}flow += MIN;}return flow;
}
char mp[maxn][maxn];
int main(){int n,m;while(scanf("%d%d",&n,&m) && n+m){init();int mcnt = 0,hcnt = 0;for(int i = 1;i <= n;i++){scanf("%s",mp[i] + 1);for(int j = 1;j <= m;j++){if(mp[i][j] == 'm'){man[mcnt].x = i;man[mcnt++].y = j;}else if(mp[i][j] == 'H'){house[hcnt].x = i;house[hcnt++].y = j;}}}//建图for(int i = 1;i <= hcnt;i++){   //和超级源点连addEdge(0,i,1,0);}for(int i = hcnt + 1;i <= 2*hcnt;i++){  //和超级汇点连addEdge(i,2*hcnt + 1,1,0);}for(int i = 0;i < mcnt;i++){for(int j = 0;j < mcnt;j++){int pay = abs(house[i].x - man[j].x) + abs(house[i].y - man[j].y);addEdge(i + 1,j + mcnt + 1,1,pay);}}int cost = 0;MCMF(0,2*hcnt + 1,cost);printf("%d\n",cost);}return 0;
}

转载于:https://www.cnblogs.com/KirinSB/p/9408752.html

POJ 2195 Going Home(最小费用最大流)题解相关推荐

  1. POJ 2195 Going Home 最小费用最大流

    这题目同时也可以用KM()算法做,最求小权值匹配而已,权值设置为负数就行,具体KM算法参照:http://blog.csdn.net/cnh294141800/article/details/1895 ...

  2. POJ 2135 Farm Tour (最小费用最大流)

    Description 给出一张\(N\)个点\(M\)条边的带权无向图,结点编号从\(1\)到\(N\),求从\(1\)到\(N\)再到\(1\)的最短路,每条边最多走一次. Input 第一行给出 ...

  3. POJ - 2516 Minimum Cost 最小费用最大流

    题目链接 题意:给n,m,k表示商店数,储存店数,种类数 然后给n*k表示每个水果店需求每种种类的数量: 表示成 need[i][j] 再给m*k表示每个储存店每种种类数量: 表示成store[i][ ...

  4. POJ - 2175 Evacuation Plan(最小费用最大流+消圈定理)

    题目链接:点击查看 题目大意:给出n个建筑物和m个避难所,每个建筑物中的人需要到避难所中去避难,规定花费是建筑物和避难所的曼哈顿距离+1,现在给出一种路线方案,问这个方案是不是最优的,如果不是,输出比 ...

  5. POJ - 2516 Minimum Cost(最小费用最大流)

    题目链接:点击查看 题目大意:给出n个买家,m个货点,以及k种货物,接下来按照顺序依次给出一个n*k的矩阵,表示每个买家对于每种货物的需求,一个m*k的矩阵,表示每个货点能供给货物的数量,k个n*m的 ...

  6. POJ - 2135 Farm Tour(最小费用最大流)

    题目链接:点击查看 题目大意:给出一个由n个点和m条边组成的无向图,每条边都有权值,求点1->点n->点1的最短路,且要求每条路至多经过一次,并使得途径的权值和最小 题目分析:虽然题目要求 ...

  7. POJ - 2195 Going Home(二分图最小权匹配+KM+思维建边/最小费用最大流)

    题目链接:点击查看 题目大意:给出一个n*m的地图,现在有一定数量的小人要回到屋子里去,题目保证图中的小人和屋子的数量是一致的,小人回到小屋的距离是两个点坐标的曼哈顿距离,每个小屋只能容纳一个小人,现 ...

  8. poj 2516(最小费用最大流)

    其实题意很明确,最小费用最大流, 但是我这2货就建图就太二了, 我把所有的情况都弄到一个图里面. 总的点数有5000个,加上这么多的边,果断TLE... 后面知道第k个的情况是独立的,所以可以分成K次 ...

  9. poj 3422 Kaka's Matrix Travels(最小费用最大流)

    题目链接 Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9394   Accep ...

  10. 最小费用最大流及习题(poj)

    该算法讲解来源:https://www.cnblogs.com/gtarcoder/p/4890739.html 最小费用最大流 通过EK,Dinic,ISAP算法可以得到网络流图中的最大流,一个网络 ...

最新文章

  1. Java,Hello world 欢迎进入Java世界
  2. 哈佛结构和冯诺依曼结构区别。
  3. android 网络广播 类似QQ动态检查网络
  4. OpenGL ES着色器语言之变量和数据类型
  5. php 调用php webservice
  6. win8配置iis8.0+php+mysql+zend_IIS下配置Php+Mysql+zend的图文教程
  7. api接口怎么写_面向声明式API编程(DAP)
  8. IE11下用forms身份验证的问题
  9. 研究Java 9 Money and Currency API(JSR 354)
  10. 搜索算法(三)--DFS/BFS求解宝岛探险问题(JAVA )
  11. cloudflare 批量修改域名DNS
  12. 牛客寒假算法基础集训营5 炫酷数字 (暴力)
  13. 工欲善其事 必先利其器
  14. Android对话框动态加载布局
  15. SqlServer高级存储过程
  16. 软件著作权人享有的权利
  17. web扫描器之Nessus
  18. 京东店铺如何获取流量
  19. 存储基础知识——SAN
  20. md5加密以及可逆的加密解密算法

热门文章

  1. html中表格内容居右的写法
  2. vb中WindowsMediaPlayer的常用属性和方法
  3. MIT博士小姐姐的机器学习入门教程开课!碎片时间服用,每周一更 | 资源
  4. 新年快乐!这是份值得收藏的2017年AI与深度学习要点大全
  5. MOSS 2018 回顾:向 40 余个开源项目捐赠 97 万美元
  6. 从在浏览器中输入URL到页面渲染出来的完整过程是怎样的?
  7. JAVA类的无参方法
  8. ubuntu安装perl模块
  9. ArchLinux借助Winetricks-zh安裝WineQQ8.1
  10. 正则表达式教程之模式修正符