[luogu2172] 部落战争
题面
我们可以将'.'抽象为一个可以通过的点, 将'x'抽象为一个不可通过的点.
那么题意便可以转化为: 一条路径可以看做从任意一个没有到达过的可通过的点出发到任意一个其他的可以通过却没有被到达过的点的一条路径, 要使每个点都被经过, 并且每个点都只能被经过一次, 这不是网络流中的最小路径覆盖吗, 大家可以去看一下魔术球问题, 魔术球问题就是最小路径覆盖的板子题.
对于这种题目, 我们将图中的每一个点拆为两个点<i, a>, <i, b>, 从源点向<i, a>连边, 从<i, b>向汇点连边, 若可从点\(i\)到达点\(j\), 就从点<i, a>向点<j, b>连一条边, 由于每个点都只能出现一次, 所以这些边的容量都是1, 然后跑一遍最大流即可, 这里还要注意一下的是, 军队只能向下走, 所以八个方向变为了四个方向, 分别是(c, r), (c, -r), (r, c), (r, -c).
跑完了最大流之后, 答案怎样统计呢, 我们最初每个可通过的点都是一条边, 所以最初有'.'的点数这么多条边, 我们不妨设这个数为\(sum\), 那么每次从点\(i\)向点\(j\)连边, 其实就意味着将两点之间的路径合并, 那么就会减少一条边, 我们又知道一个定理:最小点(在这个题中是路径(覆盖 = 点数 - 最大独立集 = 点数 - 最小割 = 点数 - 最大流, 所以最后的答案便是\(sum\) - \(dinic()\)的值, \(dinic()\)是一个函数, 他返回的是最大流的流量.
接下来还是看代码吧, 感觉解析应该没什么人会看...
具体代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define INF 1e9
using namespace std;
int m, n, R, C, mapp[105][105], u[4], v[4], S, T, head[100005], cnt = 1, cur[100005], d[100005], vis[100005], ans, sum;
struct node
{
int to, flow, next;
} edge[1000005];
inline int read()
{
int x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * w;
}
inline void add(int u, int v, int w)
{
edge[++cnt] = { v, w, head[u] }; head[u] = cnt;
edge[++cnt] = { u, 0, head[v] }; head[v] = cnt;
}
bool bfs()
{
memset(d, 0, sizeof(d)); d[S] = 1;
queue<int> q; q.push(S);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = head[u]; i; i = edge[i].next)
{
int v = edge[i].to;
if(!d[v] && edge[i].flow > 0) { d[v] = d[u] + 1; q.push(v); }
}
}
return d[T];
}
int dfs(int u, int a)
{
if(u == T || !a) return a;
int flow = 0;
for(int &i = cur[u]; i; i = edge[i].next)
{
int v = edge[i].to;
if(d[v] == d[u] + 1 && edge[i].flow > 0)
{
int f = dfs(v, min(a, edge[i].flow));
a -= f; flow += f; edge[i].flow -= f; edge[i ^ 1].flow += f;
}
if(!a) break;
}
if(a) d[u] = -1;
return flow;
}
int dinic()
{
int flow = 0;
while(bfs())
{
memcpy(cur, head, sizeof(head));
flow += dfs(S, INF);
}
return flow;
}
int main()
{
m = read(); n = read(); R = read(); C = read();
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
{
char c; cin>>c;
mapp[i][j] = (c == 'x');
if(mapp[i][j] == 1) sum++;
}
u[0] = C; u[1] = C; u[2] = R; u[3] = R; v[0] = R; v[1] = -R; v[2] = -C; v[3] = C;
S = 2 * m * n + 1; T = S + 1;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
{
add(S, (i - 1) * n + j, 1);
add((i - 1) * n + j + m * n, T, 1);
if(!mapp[i][j])
for(int k = 0; k < 4; k++)
{
int x = i + u[k], y = j + v[k];
if(x >= 1 && x <= m && y >= 1 && y <= n && !mapp[x][y]) add((i - 1) * n + j, (x - 1) * n + y + m * n, 1);
}
}
printf("%d\n", m * n - sum - dinic());
return 0;
}
话说为啥我自己的博客二级标题总是显示不出来呢
[luogu2172] 部落战争的更多相关文章
- BZOJ2150: 部落战争
题解: 把每个点拆成入点和出点,因为必须经过一次且只能经过一次.所以在两个点之间连一条上界=下界=1的边. 然后再s到每个入点连边,每个出点向t连边,点与点之间... 求最小流就可以过了... (感觉 ...
- BZOJ 2150: 部落战争 最大流
2150: 部落战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...
- BZOJ-2150部落战争(最小路径覆盖)
2150: 部落战争 Time Limit: 10 Sec Memory Limit: 259 MB Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国 ...
- 【BZOJ5317】[JSOI2018]部落战争(凸包,闵可夫斯基和)
[BZOJ5317][JSOI2018]部落战争(凸包,闵可夫斯基和) 题面 BZOJ 洛谷 题解 很明显我们只需要两个凸包\(A,B\). 假设询问给定的方向向量是\(v\). 那么现在就是判断\( ...
- 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】
P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...
- 【BZOJ2150】部落战争 最小流
[BZOJ2150]部落战争 Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇, ...
- [bzoj2150]部落战争_二分图最小路径覆盖
部落战争 bzoj-2150 题目大意:题目链接. 注释:略. 想法: 显然是最小路径覆盖,我们知道:二分图最小路径覆盖等于节点总数-最大匹配. 所以我们用匈牙利或者dinic跑出最大匹配,然后用总结 ...
- bzoj2150: 部落战争(匈牙利)
2150: 部落战争 题目:传送门 题解: 辣鸡数据..毁我AC率 先说做法,很容易就可以看出是二分图匹配的最小路径覆盖(可能是之前不久刚做过类似的题) 一开始还傻逼逼的去直接连边然后准备跑floyd ...
- P2172 [国家集训队]部落战争(最小路径覆盖)
P2172 [国家集训队]部落战争 每个点仅走一次:最小路径覆盖 套路地拆点,具体看代码中的$draw()$ 流量每增加1,意味着一支军队可以多走一格,代价减少1 最后答案即为总点数$-dinic() ...
随机推荐
- [日常] Go语言圣经-Slice切片习题
1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型:slice的语法和数组很像,只是没有固定长度而已,slice的底 ...
- JAVA通过XPath解析XML性能比较
转自[http://www.cnblogs.com/mouse-coder/p/3451243.html] 最近在做一个小项目,使用到XML文件解析技术,通过对该技术的了解和使用,总结了以下内容. 1 ...
- Servlet基础知识点整理
常用注解 官方文档:https://docs.oracle.com/javaee/7/api/toc.htm WebServlet @WebServlet用于定义一个Servlet,等价于下面的xml ...
- MVC 、JDBC、SQL、DBMS、RDBMS、DDL、DML、DCL
MVC: 全称:Model View Controller: 解释:模型(model)-视图(view)-控制器(controller) Model(模型)表示应用程序核心(比如数据库记录列表). V ...
- JS 闭包 p5
终于到闭包了,写了一晚上,好激动: 首先闭包,个人是这样理解的(比较好记):闭包是一种能力,是一种可以访问内部函数作用域的能力或者说是一种行使权力,一旦你拥有这个能力,你将可以访问内部函数的作用域.
- js实现分享到QQ
js代码 <script src="http://connect.qq.com/widget/loader/loader.js" widget="shareqq&q ...
- AsnycLocal与ThreadLocal
AsnycLocal与ThreadLocal AsnyncLocal与ThreadLocal都是存储线程上下文的变量,但是,在实际使用过程中两者又有区别主要的表现在: AsyncLocal变量可以在父 ...
- SpringCloud 组件Eureka参数配置项详解
Eureka涉及到的参数配置项数量众多,它的很多功能都是通过参数配置来实现的,了解这些参数的含义有助于我们更好的应用Eureka的各种功能,下面对Eureka的配置项做具体介绍,供大家参考. Eure ...
- dcloud资源升级方式更新app
var wgtVer = null; plus.runtime.getProperty(plus.runtime.appid, function(inf) { wgtVer = inf.version ...
- 在Docker Swarm上部署Apache Storm:第2部分
[编者按]本文来自 Baqend Tech Blog,描述了如何在 Docker Swarm,而不是在虚拟机上部署和调配Apache Storm集群.文章系国内 ITOM 管理平台 OneAPM 编译 ...