HDOJ:1533-Going Home(最小费用流)
题目链接: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(最小费用流)的更多相关文章
- 最大流增广路(KM算法) HDOJ 1533 Going Home
题目传送门 /* 最小费用流:KM算法是求最大流,只要w = -w就可以了,很经典的方法 */ #include <cstdio> #include <cmath> #incl ...
- HDU 4067 hdoj 4067 Random Maze 最小费用流
给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...
- hdu 1533 Going Home 最小费用流
构建地图非常easy bfs预处理地图.距离的成本 来源所有m建方,流程1费0 m所有H建方,流程1距离成本 H汇点建设成为各方.流程1费0 #include<cstdio> #inclu ...
- hdoj 1533 Going Home 【最小费用最大流】【KM入门题】
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- HDOJ的题目分类
模拟题, 枚举 1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 10 ...
- hdoj分类
http://blog.csdn.net/lyy289065406/article/details/6642573 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 ...
- HDOJ题目分类
模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...
- HDU——PKU题目分类
HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...
- [转] HDU 题目分类
转载来自:http://www.cppblog.com/acronix/archive/2010/09/24/127536.aspx 分类一: 基础题:1000.1001.1004.1005.1008 ...
- HDU ACM 题目分类
模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...
随机推荐
- Hyperledger Fabric 1.0 学习搭建 (二)--- 源码及镜像文件处理
2.1下载Fabric源码下载Fabric源码是因为要用到源码中提到的列子和工具, 工具编译需要用到go语言环境, 因此需要把源码目录放到$GOPATH下. 通过1.3中go的安装配置, $GOPAT ...
- 位运算(Bit Manipulation)在算法中的应用
最近刷LettCode,遇到几个没思路的算法题,都是关于位运算的 # 136 Single Number Given a non-empty array of integers, every elem ...
- February 22 2017 Week 8 Wednesday
There is only one happiness in life, to love and be loved. 生命中只有一种幸福,爱与被爱. If you think you are not ...
- .net 流(Stream) - 文件流、内存流、网络流
转自:http://www.oseye.net/user/kevin/blog/85 一.文件流 FileStream FileStream流继承与Stream类,一个FileStream类的实例实际 ...
- hosts配置
转自:http://www.cnblogs.com/ylemzhang/archive/2011/10/19/2217187.htm 注意: hosts文件不支持端口映射 如果指定端口参考: //直 ...
- 鉴定JavaScript中的数据类型
众所周知,JavaScript是一门弱类型的语言,但是这并不代表JavaScript中没有数据类型.JavaScript中常见的数据类型有string.number.object等等,通常我们使用ty ...
- iText中输出 中文
iText中输出中文,有三种方式: 1.使用iTextAsian.jar中的字体 BaseFont.createFont("STSong-Light", "UniG ...
- ios 线程同步
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/ThreadSafe ...
- c++ 基础用法、基础知识以及一些常规的操作
1.二叉平衡树:左子树和右子树的深度差小于等于1 2.二叉搜索树:左子树小于根节点的值,右子树大于根结点的值 3.队列:push(),pop(),front(),back(),empty(),size ...
- bagging 和boosting的概念和区别
1.先弄清楚模型融合中的投票的概念 分为软投票和硬投票,硬投票就是几个模型预测的哪一类最多,最终模型就预测那一类,在投票相同的情况下,投票结果会按照分类器的排序选择排在第一个的分类器结果.但硬投票有个 ...