Going Home POJ - 2195 (最小费用最大流)
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point.
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
Input
Output
Sample Input
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
Sample Output
2
10
28 思路
应该算是这个算法的板子题了,感觉还是只有看自己的代码才是最容易懂的。
cap表示边的容量,w表示费用。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1024;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);
int n,m;
char mp[108][108];
struct node
{
int x,y;
}p1[maxn],p2[maxn];
int Head[maxn],Next[maxn*maxn],v[maxn*maxn],w[maxn*maxn],cap[maxn*maxn],cnt;
int t1,t2;int ans;
void init()
{
t1=1;cnt=t2=ans=0;
memset(Head,-1,sizeof(Head));
} void add(int x,int y,int z,int f){
// cout<<x<<" "<<y<<" "<<z<<endl;
v[cnt]=y;
w[cnt]=z;
cap[cnt]=f;
Next[cnt]=Head[x];
Head[x]=cnt++; v[cnt]=x;
w[cnt]=-z;
cap[cnt]=0;
Next[cnt]=Head[y];
Head[y]=cnt++;
}
bool vis[maxn];
int dis[maxn];
int prevv[maxn],preve[maxn];
int s,t;
bool spfa()
{
queue<int>q;
memset(vis,0,sizeof(vis));
for(int i=1;i<=t;i++){
dis[i]=inf;
} dis[s]=0;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int k=Head[u];k!=-1;k=Next[k]){
if(cap[k]&&dis[v[k]]>dis[u]+w[k]){
dis[v[k]]=dis[u]+w[k];
prevv[v[k]]=u;
preve[v[k]]=k; if(!vis[v[k]]){
vis[v[k]]=true;
q.push(v[k]);
}
}
}
}
// for(int i=1;i<=t;i++){
// cout<<dis[i]<<" ";
// }
// cout<<endl;
// getchar();getchar();
if(dis[t]==inf){return false;}
else return true;
}
int min_cost_flow()
{
// fuck("???")
while(spfa()){
// cout<<"____"<<endl;
for(int i=t;i!=s;i=prevv[i]){
int k=preve[i];
cap[k]-=1;
cap[k^1]+=1;
}
// cout<<endl;
ans+=dis[t];
} } int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
init();
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;j++){
if(mp[i][j]=='m'){p1[++t1]=node{i,j};}
else if(mp[i][j]=='H'){p2[++t2]=node{i,j};}
}
}
s=1;t=t1+t2+1;
for(int i=2;i<=t1;i++){
add(s,i,0,1);
for(int j=1;j<=t2;j++){
add(i,j+t1,abs(p1[i].x-p2[j].x)+abs(p1[i].y-p2[j].y),inf);
}
}
for(int i=1;i<=t2;i++){
add(i+t1,t,0,1);
} min_cost_flow();
printf("%d\n",ans);
} return 0;
}
Going Home POJ - 2195 (最小费用最大流)的更多相关文章
- poj 2195 最小费用最大流模板
/*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accept ...
- POJ - 2195 最小费用最大流
题意:每个人到每个房子一一对应,费用为曼哈顿距离,求最小的费用 题解:单源点汇点最小费用最大流,每个人和房子对于建边 #include<map> #include<set> # ...
- poj 3422(最小费用最大流)
题目链接:http://poj.org/problem?id=3422 思路:求从起点到终点走k次获得的最大值,最小费用最大流的应用:将点权转化为边权,需要拆点,边容量为1,费用为该点的点权,表示该点 ...
- POJ 2516 最小费用最大流
每一种货物都是独立的,分成k次最小费用最大流即可! 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E[pe[v]^ ...
- POJ 2135 最小费用最大流 入门题
Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19207 Accepted: 7441 Descri ...
- poj 2135最小费用最大流
最小费用最大流问题是经济学和管理学中的一类典型问题.在一个网络中每段路径都有"容量"和"费用"两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择 ...
- poj 3680(最小费用最大流)
题目链接:http://poj.org/problem?id=3680 思路:因为N<=200,而区间范围为[1,100000],因此需要离散化,去重,然后就是建图了相连两点连边,容量为k,费用 ...
- POJ 2315 最小费用最大流
从1走到N然后从N走回来的最短路程是多少? 转换为费用流来建模. 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E ...
- POJ 2135 最小费用最大流
题目链接 Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18961 Accepted: 7326 D ...
- POJ 2195:Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...
随机推荐
- js外部调用layui.use中的函数的写法
layui模块化的写法固然不错,但也有让人不适应的一些地方 外部调用函数的写法就让人不太舒服 需要在函数名前面加上window这个前缀,就不太舒服 补充:window前缀,是全局变量的声明方式 如下: ...
- C#使用WebClient下载文件到本地目录
C#使用WebClient下载文件到本地目录. 1.配置本地目录路径 <appSettings> <!--文件下载目录--> <add key="Downloa ...
- react 入坑笔记(二) - State
React State 一. state 大致思想:在 react 中,每个组件都是一个状态机,通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致.React 里,只需更新组件的 ...
- string.Format出现异常:输入字符串的格式不正确 Exception during StringFormat
错误信息:Exception during StringFormat:输入字符串的格式不正确 “System.FormatException”类型的未经处理的异常在 mscorlib.dll 中发生 ...
- HTML5 ----- deviceorientation API
当我们把设备举到面前,就是坐公交车时玩手机的状态,手机的宽度(水平方向)就是X轴,从左向右依次变大:手机的高度(垂直方向)就是y轴,从下到上依次变大: 眼光盯着屏幕,我们的视线就是Z轴,离我们的眼睛越 ...
- HDU1251 字典树板子题
题意:中文题,统计以某字符串作为前缀的字符串个数 刚学字典树,理解起来十分简单,就是维护一个多叉树,这里用的是链表版本,后面就用的是数组版本了,个人更喜欢数组版本,这里的链表版本就因为 莫名其妙的错误 ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- POJ 3667 Hotel(算竞进阶习题)
线段树区间染色 题目要求最大的连续段的左端点,我们在查询的时候返回最左端即可,注意查找顺序,应该从左到右!! 另外这类染色的push_down其实比较简单,直接染成上一层的标记即可 push_up和连 ...
- MobaXterm之取消自动关闭连接 Network error :Connection timed out
连一会就出现连接重来的问题 配置如下.
- 自学Python之路-Python基础+模块+面向对象+函数
自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的 ...