BZOJ 2150. 部落战争(最小路径覆盖问题)【BZOJ千题计划】
整理的算法模板合集: ACM模板
点我看算法全家桶系列!!!
实际上是一个全新的精炼模板整合计划
刷题就图一乐
题目链接
https://hydro.ac/d/bzoj/p/2150
是 hydro 的 BZOJ 修复工程 !
题目描述
lanzerb 的部落在 A 国的上部,他们不满天寒地冻的环境,于是准备向 A 国的下部征战来获得更大的领土。A 国是一个 m×nm\times nm×n 的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住。lanzerb 把自己的部落分成若干支军队,他们约定:
- 每支军队可以从任意一个城镇出发,并只能从上往向下征战,不能回头。途中只能经过城镇,不能经过高山深涧。
- 如果某个城镇被某支军队到过,则其他军队不能再去那个城镇了。
- 每支军队都可以在任意一个城镇停止征战。
- 所有军队都很奇怪,他们走的方法有点像国际象棋中的马。不过马每次只能走 1×21\times 21×2 的路线,而他们只能走 r×cr\times cr×c 的路线。lanzerb 的野心使得他的目标是统一全国,但是兵力的限制使得他们在配备人手时力不从心。假设他们每支军队都能顺利占领这支军队经过的所有城镇,请你帮 lanzerb 算算至少要多少支军队才能完成统一全国的大业。
输入格式
第一行包含 444 个整数 m,n,r,cm,n,r,cm,n,r,c,意义见问题描述。接下来 mmm 行每行一个长度为 nnn 的字符串。如果某个字符是 .
,表示这个地方是城镇;如果这个字符是 x
,表示这个地方是高山深涧。
输出格式
输出一个整数,表示最少的军队个数。
样例输入 #1
3 3 1 2
...
.x.
...
样例输出 #1
4
样例输入 #2
5 4 1 1
....
..x.
...x
....
x...
样例输出 #2
5
数据规模与约定
对于 100%100\%100% 的数据,1≤m,n≤501\leq m,n\leq 501≤m,n≤50,1≤r,c≤101\leq r,c\leq 101≤r,c≤10。
Solution
我们的军队从某一点出发,所有经过的结点都将被占领,显然问题就等价于在一张有向图上,从任意一个点出发,每个点只能访问一次,求访问所有结点至少要几条路径。
显然就是有向图的最小路径覆盖。
我们只需要构造二分图,将原图每个顶点 i i i 拆分成二分图 X , Y X,Y X,Y 集合中的两个顶点 X i X_i Xi和 Y i Y_i Yi。对于原图中存在的每条边 ( i , j ) (i,j) (i,j),在二分图中连接边 ( X i , Y j ) (X_i,Y_j) (Xi,Yj) 。将二分图最大匹配模型转化为网络流模型,求网络最大流。
最小路径覆盖的条数,就是原图顶点数,减去二分图最大匹配数。
对于样例一
...
.x.
...
我们共有 9 − 1 9-1 9−1 个结点,建图之后二分图最大匹配为 4 4 4,共有 8 − 4 = 4 8-4=4 8−4=4 条最小路劲覆盖。
可以理解为,若两个点连接之后,路径数显然减一。总结点数减去最大连边,也即最大匹配得到的就是最小路径覆盖。
Code
#include <bits/stdc++.h>
using namespace std;
#define node(i, j) ((i - 1) * m + j)
const int maxn = 4e5 + 7, maxm = 2e6 + 7, maxs = 100 + 7, INF = 0x3f3f3f3f;
using ll = long long;int n, m, s, t, r, c;
ll ans;
int head[maxn], ver[maxm], edge[maxm], nex[maxm], tot;
bool vis[maxn];
int depth[maxn];
char ch[maxs][maxs];
int num;
int now[maxn];
queue <int> q;void add(int x, int y, int z)
{ver[tot] = y, edge[tot] = z, nex[tot] = head[x], head[x] = tot ++ ;ver[tot] = x, edge[tot] = 0, nex[tot] = head[y], head[y] = tot ++ ;
}bool bfs()
{memset(depth, 0x3f, sizeof depth);while(q.size())q.pop();q.push(s), depth[s] = 0;now[s] = head[s];while(q.size()) {int x = q.front();q.pop();for (int i = head[x]; ~i; i = nex[i]) {int y = ver[i];ll z = edge[i];if(z > 0 && depth[y] == INF) {q.push(y);now[y] = head[y];depth[y] = depth[x] + 1;if(y == t) return true;}}}return false;
}ll dfs(int x, ll flow)
{if(x == t || flow == 0) return flow;ll ans = 0, k, i;for (i = now[x]; ~i && flow; i = nex[i]) {now[x] = i;int y = ver[i];ll z = edge[i];if(z > 0 && (depth[y] == depth[x] + 1)) {k = dfs(y, min(flow, z));if(k == 0) depth[y] = INF;edge[i] -= k;edge[i ^ 1] += k;ans += k;flow -= k;}}return ans;
}ll dinic()
{ll maxflow = 0;while(bfs()) {for (int i = 1; i <= maxn; ++ i)now[i] = head[i];while(int f = dfs(s, INF))maxflow += f;}return maxflow;
}bool check(int x, int y)
{return x >= 1 && x <= n && y >= 1 && y <= m && ch[x][y] == '.';
}int main()
{memset(head, -1, sizeof head);num = 0;scanf("%d%d%d%d", &n, &m, &r, &c);s = 0;t = maxn - 1;for (int i = 1; i <= n; ++ i) for (int j = 1; j <= m; ++ j) {cin >> ch[i][j]; if(ch[i][j] == '.') {num ++ ;add(s, node(i, j), 1);add(node(i + n * m, j + n * m), t, 1);}}for (int i = 1; i <= n; ++ i) {for (int j = 1; j <= m; ++ j) {if(ch[i][j] == 'x') continue;if(check(i + r, j + c)) add(node(i, j), node(i + r + n * m, j + c + n * m), 1);if(check(i + c, j + r)) add(node(i, j), node(i + c + n * m, j + r + n * m), 1);if(check(i + c, j - r)) add(node(i, j), node(i + c + n * m, j - r + n * m), 1);if(check(i + r, j - c)) add(node(i, j), node(i + r + n * m, j - c + n * m), 1);}}cout << num - dinic() << endl;return 0;
}
BZOJ 2150. 部落战争(最小路径覆盖问题)【BZOJ千题计划】相关推荐
- bzoj2150部落战争 最小路径覆盖
http://www.lydsy.com/JudgeOnline/problem.php?id=2150 之前一直不会的二分图. 然后百度百科普及了一下有关最小路径覆盖的知识. 详情请见:http:/ ...
- bzoj 2150: 部落战争 (最小路径覆盖)
2150: 部落战争 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 879 Solved: 493 [Submit][Status][Discus ...
- (拆点+最小路径覆盖) bzoj 2150
2150: 部落战争 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 518 Solved: 298 [Submit][Status][Discus ...
- BZOJ 2150: 部落战争 最大流
2150: 部落战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...
- 51nod_2929 部落战争(DAG最小路径覆盖)
部落战争 Problem Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些 ...
- 【网络流24题】最小路径覆盖问题
[题目]1738: 最小路径覆盖问题 [题解]网络流 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没 ...
- 最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)
在讲述这两个算法之前,首先有几个概念需要明白: 二分图: 二分图又称二部图,是图论中的一种特殊模型.设G=(V,E)是一个无向图,如果顶点V可以分割为两个互不相交的子集(A,B),并且图中的每条边( ...
- 有向图最小路径覆盖方法浅析、证明 //hdu 3861
路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联. 对于一个有向无环图怎么求最小路径覆盖? 先构造二分图: 对于原图,先拆点,吧每个点i拆成ii,iii. ...
- HDU4160(最小路径覆盖问题)
题意:当满足条件wi<wj,hi<hl和li<lj时,求解通过优化嵌套给定的娃娃可以获得的最外层洋娃娃的最小数量. 思路:如果嵌套的娃娃越多,则剩下的娃娃就越少,意味着单独出来的娃娃 ...
最新文章
- R语言paste函数、paste0函数将多个输入组合成字符串实战
- caffe 编译中出现的错误——fatal error: hdf5.h: 没有那个文件或目录
- oracle Schema Object Dependencies
- springmvc+mybatis,在mybatis逆向工程的基础上使用模板自动生成controller层代码
- valid parentheses java_Valid Parentheses Java
- [bzoj2729][HNOI2012]排队 题解 (排列组合 高精)
- java学习笔记11 (构造方法 this深探)
- 去除小圆点_去除li小圆点以及解决其空格问题
- c++ 数字后加f_Pandas 实战系列:数字格式设置
- C#中的四舍五入有多坑
- h标签在seo中的作用(技术优化)
- 在Ubuntu上安装JDK、Ant、Jmeter和Jenkins
- L2-028 秀恩爱分得快(25 分)
- 软件工程 毕业论文 文献引用 中英文文献整合
- DNS解析为什么不生效?DNS解析不生效原因分析
- 在Linux下安装配置bochs,并成功跑一个简单的boot引导(超详细)
- linux每日命令,Linux日常命令整理
- [渝粤教育] 南京森林警察学院 犯罪学(王志红) 参考 资料
- win7系统安装 cygwin 的详细步骤
- Ktor: Kotlin Web后端框架 快速开始入门