整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


刷题就图一乐

题目链接

https://hydro.ac/d/bzoj/p/2150

是 hydro 的 BZOJ 修复工程 !

题目描述

lanzerb 的部落在 A 国的上部,他们不满天寒地冻的环境,于是准备向 A 国的下部征战来获得更大的领土。A 国是一个 m×nm\times nm×n 的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住。lanzerb 把自己的部落分成若干支军队,他们约定:

  1. 每支军队可以从任意一个城镇出发,并只能从上往向下征战,不能回头。途中只能经过城镇,不能经过高山深涧。
  2. 如果某个城镇被某支军队到过,则其他军队不能再去那个城镇了。
  3. 每支军队都可以在任意一个城镇停止征战。
  4. 所有军队都很奇怪,他们走的方法有点像国际象棋中的马。不过马每次只能走 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千题计划】相关推荐

  1. bzoj2150部落战争 最小路径覆盖

    http://www.lydsy.com/JudgeOnline/problem.php?id=2150 之前一直不会的二分图. 然后百度百科普及了一下有关最小路径覆盖的知识. 详情请见:http:/ ...

  2. bzoj 2150: 部落战争 (最小路径覆盖)

    2150: 部落战争 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 879  Solved: 493 [Submit][Status][Discus ...

  3. (拆点+最小路径覆盖) bzoj 2150

    2150: 部落战争 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 518  Solved: 298 [Submit][Status][Discus ...

  4. BZOJ 2150: 部落战争 最大流

    2150: 部落战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...

  5. 51nod_2929 部落战争(DAG最小路径覆盖)

    部落战争 Problem Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些 ...

  6. 【网络流24题】最小路径覆盖问题

    [题目]1738: 最小路径覆盖问题 [题解]网络流 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没 ...

  7. 最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)

    在讲述这两个算法之前,首先有几个概念需要明白: 二分图:  二分图又称二部图,是图论中的一种特殊模型.设G=(V,E)是一个无向图,如果顶点V可以分割为两个互不相交的子集(A,B),并且图中的每条边( ...

  8. 有向图最小路径覆盖方法浅析、证明 //hdu 3861

    路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联. 对于一个有向无环图怎么求最小路径覆盖? 先构造二分图: 对于原图,先拆点,吧每个点i拆成ii,iii. ...

  9. HDU4160(最小路径覆盖问题)

    题意:当满足条件wi<wj,hi<hl和li<lj时,求解通过优化嵌套给定的娃娃可以获得的最外层洋娃娃的最小数量. 思路:如果嵌套的娃娃越多,则剩下的娃娃就越少,意味着单独出来的娃娃 ...

最新文章

  1. R语言paste函数、paste0函数将多个输入组合成字符串实战
  2. caffe 编译中出现的错误——fatal error: hdf5.h: 没有那个文件或目录
  3. oracle Schema Object Dependencies
  4. springmvc+mybatis,在mybatis逆向工程的基础上使用模板自动生成controller层代码
  5. valid parentheses java_Valid Parentheses Java
  6. [bzoj2729][HNOI2012]排队 题解 (排列组合 高精)
  7. java学习笔记11 (构造方法 this深探)
  8. 去除小圆点_去除li小圆点以及解决其空格问题
  9. c++ 数字后加f_Pandas 实战系列:数字格式设置
  10. C#中的四舍五入有多坑
  11. h标签在seo中的作用(技术优化)
  12. 在Ubuntu上安装JDK、Ant、Jmeter和Jenkins
  13. L2-028 秀恩爱分得快(25 分)
  14. 软件工程 毕业论文 文献引用 中英文文献整合
  15. DNS解析为什么不生效?DNS解析不生效原因分析
  16. 在Linux下安装配置bochs,并成功跑一个简单的boot引导(超详细)
  17. linux每日命令,Linux日常命令整理
  18. [渝粤教育] 南京森林警察学院 犯罪学(王志红) 参考 资料
  19. win7系统安装 cygwin 的详细步骤
  20. Ktor: Kotlin Web后端框架 快速开始入门

热门文章

  1. "北京成功故事"系列报道之四:巴伐利亚啤酒酿造师在北京
  2. 【DB笔试面试759】在Oracle中,如果主库丢失归档文件,那么物理DG如何恢复?
  3. 3/15,别忘记维护你的权利!各地消费者协会网址、投诉电话一览表!
  4. kubernetes组件再认知
  5. 氛围灯INMP441+WS2812灯带--未完
  6. 如何区分生抽与老抽?
  7. GUI测试及GUI自动化测试
  8. 分享一个在微信上捞几万块的操作
  9. Schtasks Windows 定时任务
  10. 在Ubuntu中配置联通3G上网卡