poj 2195 Going Home
/*
做网络流的题建图真的是太重要了!
本题是将人所在的位置和房子所在的位置建立边的联系,其中man到house这一条边的流量为 1, 费用为两者的距离
而方向边的流量为 0, 费用为正向边的相反数(也就是沿着反向边进行增广时,费用要减少,更改先前错误的选择)
最后增加一个源点和一个汇点完毕(源点映射到man, house映射到汇点, 费用为0, 流量为1)
*/
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<queue>
#define Max 0x3f3f3f3f
#define N 205
using namespace std; class node
{
public:
int x, y;
}; node xyM[N];
node xyH[N];
int cost[N][N], cap[N][N];
int cntM, cntH;
int pre[N*], dist[N*], vis[N*], n, m; void addE(int i, int j, int ct, int cp)
{
cost[i][j]=ct;
cap[i][j]=cp;
cost[j][i]=-ct;
//cap[j][i]=0;
} int s, t, minCost; void buildMap()
{
int i, j;
memset(cap, , sizeof(cap));
s=; t=cntM+cntH+;
for(i=; i<cntM; ++i)
addE(, i+, , );
for(i=; i<cntH; ++i)
addE(cntM+i+, t, , );
for(i=; i<cntM; ++i)
for(j=; j<cntH; ++j)
addE(i+, cntM+j+, abs(xyM[i].x-xyH[j].x)+abs(xyM[i].y-xyH[j].y), );
} queue<int>q; int spfa()
{
int u, v;
memset(dist, 0x3f, sizeof(dist));
dist[]=;
q.push();
vis[]=;
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=;
for(v=; v<=t; ++v)
if(cap[u][v]> && dist[v]>dist[u]+cost[u][v])
{
dist[v]=dist[u]+cost[u][v];
pre[v]=u;
if(!vis[v])
{
vis[v]=;
q.push(v);
}
}
}
if(dist[t]==Max)
return ;
return ;
} void updateEdge()
{
int u, minFlow=Max;
for(u=t; u!=s; u=pre[u])//通过最短路径寻找这条路径上的最小流量
if(cap[pre[u]][u]<minFlow)
minFlow=cap[pre[u]][u];
for(u=t; u!=s; u=pre[u])
{
cap[pre[u]][u]-=minFlow;
cap[u][pre[u]]+=minFlow;
minCost+=cost[pre[u]][u];
}
} int main()
{
int i, j;
char c;
while(scanf("%d%d", &n, &m) && (n||m))
{
cntM=cntH=;
minCost=;
for(i=; i<=n; ++i)
{
getchar();
for(j=; j<=m; ++j)
{
scanf("%c", &c);
if(c=='m')
{
xyM[cntM].x=i;
xyM[cntM++].y=j;
}
else if(c=='H')
{
xyH[cntH].x=i;
xyH[cntH++].y=j;
}
}
}
buildMap();
while(spfa())
updateEdge();
printf("%d\n", minCost);
}
return ;
}
//邻接表
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define INF 0x3f3f3f3f
#define N 1000005
using namespace std; int cntH, cntM; struct node{
int x, y;
}; struct EDGE{
int u, v, cap, cost, nt;
};
EDGE edge[N]; queue<int>q;
node man[], house[];
int first[];
int dist[];
int pre[], flow[], vis[];
int cnt, t;
int minCost;
int n, m; void addEdge(int u, int v, int cap, int cost){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].cap=cap;
edge[cnt].nt=first[u];
edge[cnt].cost=cost;
first[u]=cnt++; edge[cnt].u=v;
edge[cnt].v=u;
edge[cnt].cap=;
edge[cnt].nt=first[v];
edge[cnt].cost=-cost;
first[v]=cnt++;
} void buildMap(){
memset(first, -, sizeof(first));
t=cntH+cntM+;
for(int i=; i<=cntM; ++i)
for(int j=; j<=cntH; ++j)
addEdge(i, cntM+j, , abs(man[i].x-house[j].x) + abs(man[i].y-house[j].y));
for(int i=; i<=cntM; ++i)
addEdge(, i, , );
for(int i=; i<=cntH; ++i)
addEdge(cntM+i, t, , );
} bool MCMF(){
memset(dist, 0x3f, sizeof(dist));
memset(vis, , sizeof(vis));
q.push();
flow[]=INF;
dist[]=;
vis[]=;
while(!q.empty()){
int u=q.front(); q.pop();
vis[u]=;
for(int e=first[u]; ~e; e=edge[e].nt){
int v=edge[e].v, cap=edge[e].cap, cost=edge[e].cost;
if(cap> && dist[v]>dist[u]+cost){
dist[v]=dist[u]+cost;
flow[v]=min(flow[u], cap);
pre[v]=e;
if(!vis[v]){
vis[v]=;
q.push(v);
}
}
}
}
if(dist[t]==INF) return false;
minCost+=dist[t];
int x=t;
while(x!=){
edge[pre[x]].cap-=flow[t];
edge[pre[x]^].cap+=flow[t];
x=edge[pre[x]].u;
}
return true;
} int main(){
while(scanf("%d%d", &n, &m) && (n||m)){
cnt=cntH=cntM=;
for(int i=; i<=n; ++i){
getchar();
for(int j=; j<=m; ++j){
char ch;
scanf("%c", &ch);
if(ch=='m'){
man[++cntM].x=i;
man[cntM].y=j;
}
else if(ch=='H'){
house[++cntH].x=i;
house[cntH].y=j;
}
}
}
buildMap();
minCost=;
while(MCMF());
printf("%d\n", minCost);
}
return ;
}
poj 2195 Going Home的更多相关文章
- POJ 2195 Going Home 最小费用最大流 尼玛,心累
D - Going Home Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
- POJ 2195 Going Home / HDU 1533(最小费用最大流模板)
题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...
- POJ 2195 Going Home (带权二分图匹配)
POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...
- 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 ...
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- POJ 2195:Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...
- poj 2195 KM算法
题目链接:http://poj.org/problem?id=2195 KM算法模板~ 代码如下: #include "stdio.h" #include "string ...
- Poj(2195),最小费用流,SPFA
题目链接:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- poj 2195 Going Home(最小费用最大流)
题目:http://poj.org/problem?id=2195 有若干个人和若干个房子在一个给定网格中,每人走一个都要一定花费,每个房子只能容纳一人,现要求让所有人进入房子,且总花费最小. 构造一 ...
随机推荐
- DNS的view设置
在实际的网络应用中,我们有时希望对于同一个Domain Name能够根据不同的请求IP 地址/区域,解析到不同的对应IP地址,比如:有时对于企业内部网络和外部网络希望对同一域名解析到不同的IP地址以达 ...
- php+Mysqli利用事务处理转账问题实例
本文实例讲述了php+Mysqli利用事务处理转账问题的方法.分享给大家供大家参考 <?php /**php+Mysqli利用事务处理转账问题实例 * author http://www.lai ...
- ios的网络数据下载和json解析
ios的网络数据下载和json解析 简介 在本文中,笔者将要给大家介绍如何使用nsurlconnection 从网上下载数据,以及解析json数据格式,以及如何显示数据和图片的异步下载显示. 涉及的知 ...
- (原创) 巩固理解I2C协议(MCU,经验)
题外话:这几天天气突然转冷了.今天已是11月23日了,查查黄历,昨天(11月22日)刚好是小雪,一夜温度骤降,果然老祖先的经验有灵验!冬天来了,还是多加加衣服,注意保暖! 1.Abstract ...
- C++混合编程之idlcpp教程Lua篇(8)
上一篇在这 C++混合编程之idlcpp教程Lua篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程LuaTutorial6中,同样加入了四个文件:LuaTutori ...
- [Xamarin] 從Xamarin中呼叫 *.jar 的 library - 呼叫篇 (转帖)
上篇文章我們建立一個很簡單的Library : com.example.blackfactory.UtilFunc 現在我們要在Xamarin 中呼叫囉! 首先我們要先成立一個橋接的專案 JARBri ...
- WindowsPhone技术和XNA技术
介于公司目前还没有涉及WP(WindowsPhone)项目的开发,而我本身是学习WP开发的,因此在这里稍微入门的介绍一点WP的知识. 一.简介 Windows Phone具有桌面定制.图标拖拽.滑动控 ...
- OAuth 2.0 授权原理
出处:http://www.cnblogs.com/neutra/archive/2012/07/26/2609300.html 最近在做第三方接入的,初步定下使用OAuth2协议,花了些时间对OAu ...
- Intel VT-x 基本概念
看IaaS 资料时,捎带研究下硬件虚拟化,主要参考<基于intel VT-x 的Xen 全虚拟化实现>,<intel 开发手册 第三卷 19/20章> Intel VT 是in ...
- .NET学习笔记 -- 那堆名词到底是啥(CLR、CLI、CTS、CLS、IL、JIT)
什么是CLR? CLR,公共语言运行时(Common Language Runtime)是一个由多种语言使用的“运行时”.他的核心功能包括(内存管理.程序集加载.安全性.异常处理和线程同步),可以被面 ...
