[POJ2195]Going Home(带权最大匹配,KM,最小费用流)
题目链接:http://poj.org/problem?id=2195
题意:给个图,m代表人H代表房子。每一个m要有一个H,代价是曼哈顿距离。问让所有m找到房子的最小花费。
可以直接枚举m和H建二分图跑KM。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <bitset> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 #include <ctime> 15 #include <set> 16 #include <map> 17 #include <cmath> 18 19 using namespace std; 20 21 const int maxn = 310; 22 const int inf = 0x3f3f3f3f; 23 int nx,ny; 24 int G[maxn][maxn]; 25 int linker[maxn],lx[maxn],ly[maxn]; 26 int slack[maxn]; 27 bool visx[maxn],visy[maxn]; 28 29 bool dfs(int x) { 30 visx[x] = true; 31 for(int y = 0; y < ny; y++) { 32 if(visy[y])continue; 33 int tmp = lx[x] + ly[y] - G[x][y]; 34 if(tmp == 0) { 35 visy[y] = true; 36 if(linker[y] == -1 || dfs(linker[y])) { 37 linker[y] = x; 38 return true; 39 } 40 } 41 else if(slack[y] > tmp) 42 slack[y] = tmp; 43 } 44 return false; 45 } 46 int km() { 47 memset(linker,-1,sizeof(linker)); 48 memset(ly,0,sizeof(ly)); 49 for(int i = 0;i < nx;i++) { 50 lx[i] = -inf; 51 for(int j = 0;j < ny;j++) 52 if(G[i][j] > lx[i]) 53 lx[i] = G[i][j]; 54 } 55 for(int x = 0;x < nx;x++) { 56 for(int i = 0;i < ny;i++) 57 slack[i] = inf; 58 while(true) { 59 memset(visx,false,sizeof(visx)); 60 memset(visy,false,sizeof(visy)); 61 if(dfs(x))break; 62 int d = inf; 63 for(int i = 0;i < ny;i++) 64 if(!visy[i] && d > slack[i]) 65 d = slack[i]; 66 for(int i = 0;i < nx;i++) 67 if(visx[i]) 68 lx[i] -= d; 69 for(int i = 0;i < ny;i++) { 70 if(visy[i])ly[i] += d; 71 else slack[i] -= d; 72 } 73 } 74 } 75 int res = 0; 76 for(int i = 0;i < ny;i++) 77 if(linker[i] != -1) 78 res += G[linker[i]][i]; 79 return res; 80 } 81 82 typedef pair<int,int> pii; 83 char mp[maxn][maxn]; 84 int n, m; 85 vector<pii> h, p; 86 87 int main() { 88 // freopen("in", "r", stdin); 89 while(~scanf("%d%d",&n,&m) && n+m) { 90 memset(mp, 0, sizeof(mp)); 91 h.clear(); p.clear(); 92 for(int i = 1; i <= n; i++) { 93 scanf("%s", mp[i]+1); 94 } 95 for(int i = 1; i <= n; i++) { 96 for(int j = 1; j <= m; j++) { 97 if(mp[i][j] == 'H') h.push_back(pii(i, j)); 98 else if(mp[i][j] == 'm') p.push_back(pii(i, j)); 99 } 100 } 101 memset(G, 0, sizeof(G)); 102 nx = h.size(); ny = p.size(); 103 for(int i = 0; i < h.size(); i++) { 104 for(int j = 0; j < p.size(); j++) { 105 int dis = abs(h[i].first - p[j].first) + abs(h[i].second - p[j].second); 106 G[i][j] = -dis; 107 } 108 } 109 printf("%d\n", -km()); 110 } 111 return 0; 112 }
KM
也可以用最小费用流建模。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <cassert> 8 #include <cstdio> 9 #include <bitset> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 #include <ctime> 15 #include <set> 16 #include <map> 17 #include <cmath> 18 19 using namespace std; 20 21 typedef long long LL; 22 typedef struct Node { 23 int u, v, next; 24 LL c, w; 25 }Node; 26 const int maxn = 20010; 27 const int maxm = 40010; 28 const LL mod = 0x3f3f3f3fLL; 29 const LL inf = (1LL<<55); 30 int tot, head[maxn]; 31 LL dist[maxn]; 32 LL cost, flow; 33 Node e[maxm]; 34 int pre[maxn]; 35 bool visit[maxn]; 36 queue<int> Q; 37 int S, T, N; 38 39 void init() { 40 S = T = N = 0; 41 memset(head, -1, sizeof(head)); 42 tot = 0; 43 } 44 45 void adde(int u, int v, LL c, LL w) { 46 e[tot].u = u; e[tot].v = v; e[tot].c = c; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++; 47 e[tot].u = v; e[tot].v = u; e[tot].c = 0; e[tot].w = -w; e[tot].next = head[v]; head[v] = tot++; 48 } 49 bool spfa(int s, int t, int n) { 50 int i; 51 for(i = 0; i <= n; i++) { 52 dist[i] = inf; 53 visit[i] = 0; 54 pre[i] = -1; 55 } 56 while(!Q.empty()) Q.pop(); 57 Q.push(s); 58 visit[s] = true; 59 dist[s] = 0; 60 pre[s] = -1; 61 while(!Q.empty()) { 62 int u = Q.front(); 63 visit[u] = false; 64 Q.pop(); 65 for(int j = head[u]; j != -1; j = e[j].next) { 66 if(e[j].c > 0 && dist[u] + e[j].w < dist[e[j].v]) { 67 dist[e[j].v] = dist[u] + e[j].w; 68 pre[e[j].v] = j; 69 if(!visit[e[j].v]) { 70 Q.push(e[j].v); 71 visit[e[j].v] = true; 72 } 73 } 74 } 75 } 76 if(dist[t] == inf) return false; 77 else return true; 78 } 79 LL ChangeFlow(int t) { 80 LL det = mod; 81 int u = t; 82 while(~pre[u]) { 83 u = pre[u]; 84 det = min(det, e[u].c); 85 u = e[u].u; 86 } 87 u = t; 88 while(~pre[u]) { 89 u = pre[u]; 90 e[u].c -= det; 91 e[u ^ 1].c += det; 92 u = e[u].u; 93 } 94 return det; 95 } 96 LL MinCostFlow(int s, int t, int n) { 97 LL mincost, maxflow; 98 mincost = maxflow = 0; 99 while(spfa(s, t, n)) { 100 LL det = ChangeFlow(t); 101 mincost += det * dist[t]; 102 maxflow += det; 103 } 104 cost = mincost; 105 flow = maxflow; 106 return mincost; 107 } 108 109 typedef pair<int,int> pii; 110 char mp[111][111]; 111 int n, m; 112 vector<pii> h, p; 113 114 int main() { 115 // freopen("in", "r", stdin); 116 while(~scanf("%d%d",&n,&m) && n+m) { 117 init(); 118 memset(mp, 0, sizeof(mp)); 119 h.clear(); p.clear(); 120 for(int i = 1; i <= n; i++) { 121 scanf("%s", mp[i]+1); 122 } 123 for(int i = 1; i <= n; i++) { 124 for(int j = 1; j <= m; j++) { 125 if(mp[i][j] == 'H') h.push_back(pii(i, j)); 126 else if(mp[i][j] == 'm') p.push_back(pii(i, j)); 127 } 128 } 129 S = 0, T = h.size() + p.size() + 1, N = T + 1; 130 for(int i = 0; i < h.size(); i++) adde(S, i+1, 1, 0); 131 for(int i = 0; i < p.size(); i++) adde(h.size()+i+1, T, 1, 0); 132 for(int i = 0; i < h.size(); i++) { 133 for(int j = 0; j < p.size(); j++) { 134 int dis = abs(h[i].first - p[j].first) + abs(h[i].second - p[j].second); 135 int hi = i + 1; 136 int pi = h.size() + j + 1; 137 adde(hi, pi, 1, (LL)dis); 138 } 139 } 140 cout << MinCostFlow(S, T, N) << endl; 141 } 142 return 0; 143 }
转载于:https://www.cnblogs.com/kirai/p/6769135.html
[POJ2195]Going Home(带权最大匹配,KM,最小费用流)相关推荐
- HDU 1853 HDU 3488【有向环最小权值覆盖问题 】带权二分图匹配 KM算法
HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]最小费用最大流 In the kingdom of Henryy, there are N (2 <= N <= ...
- 二分图大讲堂——彻底搞定最大匹配数(最小覆盖数)、最大独立数、最小路径覆盖、带权最优匹配
二分图匹配 二分图大讲堂--彻底搞定最大匹配数(最小覆盖数).最大独立数.最小路径覆盖.带权最优匹配(转) 文本内容框架: §1图论点.边集和二分图的相关概念和性质 §2二分图最大匹配求解 匈牙利算法 ...
- Uvalive3353 Optimal Bus Route Design 带权二分图匹配
题目描述:给出一个有向带权图,现在要求在图中找出若干个环,使得每个点恰好在一个环里,且所有环的距离之和最小,如果不能使每个点恰好在一个环里,输出"N". 思路: 将每个点u拆成u和 ...
- POJ-2195 Going Home 最小权值匹配
题意:给定一个网格图,图上有一些人要到一些房子当中去,人和房子的数量一样多,人和房子的曼哈顿距离作为行走的开销,问所有人走到房子中的最小开销. 解法:将人和房子之间两两之间建立带权边,权值为曼哈顿距离 ...
- HOJ 2739 The Chinese Postman Problem 带权有向图上的中国邮路问题
[题目大意] 带权有向图上的中国邮路问题:一名邮递员需要经过每条有向边至少一次,最后回到出发点,一条边多次经过权值要累加,问最小总权值是多少.(2 <= N <= 100, 1 < ...
- 带权二分图匹配(最小费用最大流) 8.2牛客暑期多校训练营五 E
E.room | 时间限制:1 秒 | 内存限制:256M Nowcoder University has 4n students and n dormitories ( Four students ...
- 语音识别、传统语音识别、带权有限转态转换器、深度语音识别、时序分类、CTC解码
语音识别.传统语音识别.带权有限转态转换器.深度语音识别.时序分类.CTC解码 目录
- 2017乌鲁木齐区域赛I(带权并查集)
#include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...
- BZOJ 2303 方格染色(带权并查集)
要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...
- POJ1703带权并查集(距离或者异或)
题意: 有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...
最新文章
- 移动APP开发使用什么样的原型设计工具比较合适?
- 台湾大学林轩田机器学习基石课程学习笔记10 -- Logistic Regression
- 【iMX6ULL】触觉 imx6ull开发板交叉编译环境搭建
- 【转】java io 总结(图)
- mysql select效率_Mysql优化之selectcount效率_MySQL
- (转)向SDE库中写入栅格和矢量数据
- ae导出gif插件_AE小白必看教程,围观AE老司机如何使用AE导出gif图片
- 今天开通android博客 该认真学习了
- 278.第一个错误版本(力扣leetcode) 博主可答疑该问题
- 手把手教你DosBox的配置(附下载资源)
- python入门学习随记(十二)
- Excise_day01
- 路由器wan口认证断开服务器无响应,路由器WAN口设置已断开(服务器无响应)的解决方法...
- WPS/WORD论文格式调整方法
- 照片墙(3D立体几何)
- 王道计算机组成原理第六章---总线总结
- 【清华牛人】Stanford, Caltech双料博士
- 讲解Guitar Pro 7使用向导的技巧
- MySQL的limit分页,为什么越往后翻越慢,怎么解决?
- java emoji过滤_Android中过滤Emoji表情 完整版
热门文章
- 【openjudge】字符串排序
- 已有一个名为“frmadd”的组件。组件的名称必须是唯一的,而且名称必须不区分大小
- 你可能不知道的CSS3属性: object-fit,object-position的妙用
- Java神鬼莫测之MyBatis实现分页全过程(三)
- 仍然提供32位Linux发行版,Ubuntu 20.04彻底淘汰32位映像,只提供64位映像下载
- python中format函数怎么样提取字符串里的字符_Python中用format函数格式化字符串的用法...
- java应用中如何连接dbproxy_GitHub - alchemystar/hero: 用c语言写的dbproxy
- 如何手绘表格_Word2010中怎样用画笔绘制表格
- java序列化和反序列化练习
- 服务器win10系统开机慢,Win10系统开机慢怎么办 windows10开机慢的解决方法