[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() ...
随机推荐
- 分机号-2015决赛C语言C组第一题
标题:分机号 X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位.比如: 751,520,321 都满足要求,而, 766,918,201 就不符合要 ...
- Could not transfer artifact org.apache.maven.plugins:maven-resources-plugin:pom:2.6 from/to central
问题: maven安装完成,环境变量配置没有问题,cmd窗口运行mvn compile的时候报错如下: Plugin org.apache.maven.plugins:maven-resources- ...
- [转载] MySQL的四种事务隔离级别
本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...
- SQL Server 如何添加删除外键、主键,以及更新自增属性
1.添加删除主键和外键 例如: -----删除主键约束DECLARE @NAME SYSNAMEDECLARE @TB_NAME SYSNAMESET @TB_NAME = 'Date'SELECT ...
- Java线程分析
一.Java线程的生命周期中,存在几种状态.在Thread类里有一个枚举类型State,定义了线程的几种状态 public enum State { NEW, RUNNABLE, BLOCKED, W ...
- 小程序通过用户授权获取手机号之getPhoneNumber
小程序有一个获取用户很便捷的api,就是通过getPhoneNumber获取用户的已经绑定微信的手机号码.有一点要大家注意,现在微信和注重用户体验,有些方法都是需要用户主动去触发才能调用的,比如get ...
- js-ES6学习笔记-async函数(3)
1.await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中. 2.多个await命令后面的异步操作,如果不存在继发关系,最好 ...
- CSS3多媒体查询
CSS2多媒体查询: @media规则在css2中有介绍,针对不同媒体类型(包括显示器,便携设备,电视机,等等)可以定制不同的样式规则. CSS3多媒体查询: CSS3多媒体查询继承了CSS2多媒体类 ...
- IDEA项目搭建一——使用Maven创建多模块项目
废话不多说,直接开始吧,如果有哪里写的不多的,还望指出,谢谢 一.创建空项目EmpayProject File -> New -> Project 二.添加父模块Parent Module ...
- VS2017写代码时几个常用的快捷键
说明:组合键是同时按,非组合键是按住Ctrl依次按后面的键1.格式化 格式化全部代码 Ctrl+A+K+F 格式化选中的代码 Ctrl+K+F 2.注释代码 注释代码 ...