poj-2195-Going Home(最小费用最大流模板题)
2016-05-21 19:30
465 查看
传送门
最小费用最大流模板
题意:
有n个人和n个房子,让每个人都回到一个房子里面,使得所有人走的步数和最小
建图:源点0,汇点:2*n+1,从源点到汇点建立一个容量为1,费用为0 的一条边,从每个房子到汇点建立一个容量为1,费用为0 的一条边;每个人到每个房子建立一条容量为1,费用为两者距离的边。图建好之后就可以直接求最小费用最大流了
最小费用最大流模板
题意:
有n个人和n个房子,让每个人都回到一个房子里面,使得所有人走的步数和最小
建图:源点0,汇点:2*n+1,从源点到汇点建立一个容量为1,费用为0 的一条边,从每个房子到汇点建立一个容量为1,费用为0 的一条边;每个人到每个房子建立一条容量为1,费用为两者距离的边。图建好之后就可以直接求最小费用最大流了
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define MAXN 1003 #define MAXM 40004 using namespace std; const int INF = 0x3f3f3f3f; struct EDGE{ int to, next, cap, flow, cost; }edge[MAXM]; struct Point{ int x, y; }men[MAXN], house[MAXN]; int q[MAXN*10], head[MAXN], tol, menNum, houseNum, n, m; int pre[MAXN], dis[MAXN]; bool vis[MAXN]; char g[110]; void init(){ tol = 0; menNum = 1; houseNum = 1; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int cap, int cost){ edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++; } bool spfa(int st, int en){ int rear = 0, front = 0; for (int i = 0; i <= en; i++){ dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[st] = 0; vis[st] = true; q[front++] = st; while(rear < front){ int u = q[rear++]; vis[u] = false; for (int e = head[u]; e != -1; e = edge[e].next){ int v = edge[e].to; if (edge[e].cap > edge[e].flow && dis[v] > dis[u]+edge[e].cost){ dis[v] = dis[u]+edge[e].cost; pre[v] = e; if (!vis[v]){ vis[v] = true; q[front++] = v; } } } } return pre[en] != -1; } int minCostMaxFlow(int st, int en, int &cost){ int flow = 0; while(spfa(st, en)){ int Min = INF; for (int i = pre[en]; i != -1; i = pre[edge[i^1].to]){ Min = (Min > (edge[i].cap-edge[i].flow) ? (edge[i].cap-edge[i].flow) : Min); } for (int i = pre[en]; i != -1; i = pre[edge[i^1].to]){ edge[i].flow += Min; edge[i^1].flow -= Min; cost += Min*edge[i].cost; } } return flow; } int main(){ #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif int i, j, k, cost, u, v, st, en; while(1) { scanf("%d%d", &n, &m); if (!n && !m){ break; } init(); for (i = 0; i < n; i++){ scanf("%s", g); for (j = 0; j < m; j++){ if (g[j]=='H'){ men[menNum].x = i; men[menNum].y = j; menNum++; }else if (g[j]=='m'){ house[houseNum].x = i; house[houseNum].y = j; houseNum++; } } } st = 0; en = menNum+houseNum-1; for (i = 1; i < menNum; i++){ for (j = 1; j < houseNum; j++){ addEdge(i, menNum+j-1, 1, abs(men[i].x-house[j].x)+abs(men[i].y-house[j].y)); } } cost = 0; for (i = 1; i < menNum; i++) { addEdge(0, i, 1, 0); addEdge(i+menNum-1, en, 1, 0); } minCostMaxFlow(st, en, cost); printf("%d\n", cost); } return 0; }
相关文章推荐
- django框架从零开始_011_测试view
- 寄存 【GDOI 2016 Day2】第一题 SigemaGO
- Django administration后台管理添加页面保持中文出错解决办法,'ascii' codec can't encode characters in position 0-4:
- Google工程师带你一起看2016 Google IO最酷的8项发布
- 征服go开始
- SecureCRT的logon action登录跳转设置
- Django笔记 pillow安装错误
- golang 值得注意的地方(2则)
- django--的第一个项目hello world
- Google 知道你点击了哪个网页
- Google 知道你点击了哪个网页
- go 学习笔记 - sublime text 环境配置
- ubuntu 安装go语言开发环境
- 泸州气gou
- 在Django中使用markdown
- 啦啦啦啦~Django1.96---编写第一个Django应用(6)
- Google I/O大会,炫酷产品汇总
- Algorithm-How To Identifying Same IMG
- 初探:celery在django下的应用.md
- 啦啦啦啦~Django1.96---编写第一个Django应用(5)