题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533


解题心得:

  • 第一次写最小费用流的题,去hdoj上找了一个入门级题目,建图比较简单,用了spfa和Dij两种写法。

//spfa
#include <bits/stdc++.h>
using namespace std;
const int maxn = *; struct edge{
int to, cap, dis, rev; edge(int To, int Cap, int Dis, int Rev):
to(To), cap(Cap), dis(Dis), rev(Rev) {}
}; //感觉这里写得超级智障,懒得改了
struct men {
int x,y;
}; struct House {
int x,y;
}; vector <edge> ve[maxn];
vector <men> man;
vector <House> house;
int n, m, S, T;
char maps[maxn][maxn]; void init() {
S = ;
man.clear();
house.clear();
for(int i=;i<maxn;i++)
ve[i].clear();
for(int i=;i<=n;i++)
scanf("%s",maps[i]+);
for(int i=;i<=n;i++) {
for(int j=;j<=m;j++) {
if(maps[i][j] == 'm') {
men now;
now.x = i;
now.y = j;
man.push_back(now);
} else if(maps[i][j] == 'H') {
House temp;
temp.x = i;
temp.y = j;
house.push_back(temp);
}
}
}
T = man.size() + house.size() + ;
} void build_adge(int s, int to, int dis) {
ve[s].push_back(edge(to, , dis, ve[to].size()));
ve[to].push_back(edge(s, , -dis, ve[s].size()-));
} void add_adge() {
for(int i=;i<man.size();i++) {
build_adge(S, i+, );
for(int j=;j<house.size();j++) {
int dis = abs(man[i].x - house[j].x) + abs(man[i].y - house[j].y);
build_adge(i+, man.size()+j+, dis);
}
}
for(int i=;i<house.size();i++) {
build_adge(i++man.size(), T, );
}
} int dist[maxn], preve[maxn], prevv[maxn];
bool vis[maxn];
bool SPFA() {
memset(preve, , sizeof(preve));
memset(vis, , sizeof(vis));
memset(prevv, , sizeof(prevv));
memset(dist, 0x3f, sizeof(dist));
dist[S] = ;
queue <int> qu;
qu.push(S);
while(!qu.empty()) {
int now = qu.front() ;qu.pop();
vis[now] = false;
for(int i=;i<ve[now].size();i++) {
edge &e = ve[now][i];
if(dist[e.to] > dist[now] + e.dis && e.cap > ) {
dist[e.to] = dist[now] + e.dis;
prevv[e.to] = now;
preve[e.to] = i;
if(!vis[e.to]) {
qu.push(e.to);
vis[e.to] = true;
}
}
}
}
return dist[T] != 0x3f3f3f3f;
} int min_cost_flow() {
int ans = ;
while(SPFA()) {
for(int v = T; v!=S ; v =prevv[v]) {
edge &e = ve[prevv[v]][preve[v]];
e.cap -= ;
ve[v][e.rev].cap += ;
ans += e.dis;
}
}
return ans;
} int main() {
while(scanf("%d%d",&n,&m) && n+m) {
init();
add_adge();
printf("%d\n",min_cost_flow());
}
return ;
}

Dij

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
const int maxn = *; struct edge{
int to, cap, dis, rev; edge(int To, int Cap, int Dis, int Rev):
to(To), cap(Cap), dis(Dis), rev(Rev) {}
}; struct men {
int x,y;
}; struct House {
int x,y;
}; vector <edge> ve[maxn];
vector <men> man;
vector <House> house;
int n, m, S, T, h[maxn];
char maps[maxn][maxn]; void init() {
S = ;
man.clear();
house.clear();
memset(h, , sizeof(h));
for(int i=;i<maxn;i++)
ve[i].clear();
for(int i=;i<=n;i++)
scanf("%s",maps[i]+);
for(int i=;i<=n;i++) {
for(int j=;j<=m;j++) {
if(maps[i][j] == 'm') {
men now;
now.x = i;
now.y = j;
man.push_back(now);
} else if(maps[i][j] == 'H') {
House temp;
temp.x = i;
temp.y = j;
house.push_back(temp);
}
}
}
T = man.size() + house.size() + ;
} void build_adge(int s, int to, int dis) {
ve[s].push_back(edge(to, , dis, ve[to].size()));
ve[to].push_back(edge(s, , -dis, ve[s].size()-));
} void add_adge() {
for(int i=;i<man.size();i++) {
build_adge(S, i+, );
for(int j=;j<house.size();j++) {
int dis = abs(man[i].x - house[j].x) + abs(man[i].y - house[j].y);
build_adge(i+, man.size()+j+, dis);
}
}
for(int i=;i<house.size();i++) {
build_adge(i++man.size(), T, );
}
} int dist[maxn], preve[maxn], prevv[maxn];
bool Dij() {
memset(preve, , sizeof(preve));
memset(prevv, , sizeof(prevv));
memset(dist, 0x3f, sizeof(dist));
dist[S] = ;
priority_queue <P, vector<P>, greater<P> > qu;
qu.push(make_pair(,));
while(!qu.empty()) {
P now = qu.top(); qu.pop();
int pos = now.second;
if(dist[pos] < now.first)
continue;
for(int i=;i<ve[pos].size();i++) {
edge &e = ve[pos][i];
if(e.cap > && dist[e.to] > dist[pos] + e.dis + h[pos] - h[e.to]) {
dist[e.to] = dist[pos] + e.dis + h[pos] - h[e.to];
prevv[e.to] = pos;
preve[e.to] = i;
qu.push(make_pair(dist[e.to], e.to));
}
}
}
return dist[T] != 0x3f3f3f3f;
} int min_cost_flow() {
int ans = ;
while(Dij()) {
for(int i=;i<=T;i++)
h[i] += dist[i];
ans += h[T];
for(int v = T; v!=S ; v =prevv[v]) {
edge &e = ve[prevv[v]][preve[v]];
e.cap -= ;
ve[v][e.rev].cap += ;
}
}
return ans;
} int main() {
while(scanf("%d%d",&n,&m) && n+m) {
init();
add_adge();
printf("%d\n",min_cost_flow());
}
return ;
}

HDOJ:1533-Going Home(最小费用流)的更多相关文章

  1. 最大流增广路(KM算法) HDOJ 1533 Going Home

    题目传送门 /* 最小费用流:KM算法是求最大流,只要w = -w就可以了,很经典的方法 */ #include <cstdio> #include <cmath> #incl ...

  2. HDU 4067 hdoj 4067 Random Maze 最小费用流

    给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...

  3. hdu 1533 Going Home 最小费用流

    构建地图非常easy bfs预处理地图.距离的成本 来源所有m建方,流程1费0 m所有H建方,流程1距离成本 H汇点建设成为各方.流程1费0 #include<cstdio> #inclu ...

  4. hdoj 1533 Going Home 【最小费用最大流】【KM入门题】

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  5. HDOJ的题目分类

    模拟题, 枚举 1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 10 ...

  6. hdoj分类

    http://blog.csdn.net/lyy289065406/article/details/6642573 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 ...

  7. HDOJ题目分类

    模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...

  8. HDU——PKU题目分类

    HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...

  9. [转] HDU 题目分类

    转载来自:http://www.cppblog.com/acronix/archive/2010/09/24/127536.aspx 分类一: 基础题:1000.1001.1004.1005.1008 ...

  10. HDU ACM 题目分类

    模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...

随机推荐

  1. 马云18年前制止偷井盖视频走红 2013-05-10 11:00:37 来源: 新快报(广州) 有0人参与 分享到 网易微博 新浪微博 腾讯空间 人人网 有道云笔记 在一次访谈中,即将卸任阿里巴巴CEO的马云自曝了他第一次上电视是在1995年。“我刚开始创

    马云18年前制止偷井盖视频走红 2013-05-10 11:00:37 来源: 新快报(广州) 有0人参与   分享到 网易微博 新浪微博 腾讯空间 人人网 有道云笔记 在一次访谈中,即将卸任阿里巴巴 ...

  2. Hibernate映射Map属性2

    Hibernate在映射Map属性时生成映射文件.需要注意的一些地方.下面是我的一个例子. Java类如下 public class NameAndNumber { private Integer i ...

  3. Ubuntu14.04安装PowerDNS踩坑实录

    公司要使用PowerDNS,作为内网域名解析的工具.让我和另一组的同事学一下如何配置及调优.所以先找了两台服务器试着安装一下.这一装就是一个礼拜,经历了大大小小的坑,记下来以后可能需要参考.安装过程如 ...

  4. is和as在类型转换时的性能差异

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/xxdddail/article/details/36655219 is和as是.NET中经常使用的操 ...

  5. 优秀的WEB前端开发框架:Bootstrap!

    其实早就对Bootstrap有所耳闻,大概了解这哥们是做WEB前端的 但直到昨天以前,还没有对他产生任何深入了解的兴趣 冷落他的主要原因还是觉得会束缚手脚,毕竟自己多年来在WEB前端的积累一直没有停滞 ...

  6. BZOJ1879:[SDOI2009]Bill的挑战(状压DP)

    Description Input 本题包含多组数据.  第一行:一个整数T,表示数据的个数.  对于每组数据:  第一行:两个整数,N和K(含义如题目表述).  接下来N行:每行一个字符串. T ≤ ...

  7. php 多种输入参数完整性检查

    说明:(1)输入可能有多重类型的输入,即需要对输入参数进行多次匹配. (2)希望能够返回缺少的参数 代码如下: /** * @param $param 输入参数 (get,post 参数) * @pa ...

  8. springmvc小结(上)

    1.springmvc的整体结构以及流程 ①.前端控制器:只需要在web.xml文件中配置即可 作用:接受请求,处理响应结果,转发器,中央处理器 ②.处理器映射器:根据请求的url找到相应的Handl ...

  9. VBA与宏

    VBA与宏 ====== 刚开始的内容听起来很枯燥,请大家不要分心,耐着性子看下去,兴趣总是慢慢积累的. ----------------------------------------------- ...

  10. 如何指定安装webpack

    在此我要推荐webpack简易学习教程:https://www.runoob.com/w3cnote/webpack-tutorial.html 大家可以参考这个菜鸟教程,但是这个菜鸟教程有其局限性, ...