[LOJ#3022][网络流]「CQOI2017」老 C 的方块
定义有特殊边相邻的格子颜色为黑,否则为白
可以看出,题目给出的限制条件的本质是如果两个小方块所在的格子 \(x\) 和 \(y\) 为两个相邻的黑格,那么 \(x\) 和 \(y\) 之间必然有一者满足其上下左右的所有白格内都没有小方块
即对于这样的 \(x\) 和 \(y\) ,需要以下三个条件至少满足一个:
(1)用 \(\min(w_x,w_y)\) 的代价删除 \(x\) 和 \(y\) 上的其中一个小方块
(2)把与 \(x\) 相邻的白格内的小方块全部删掉
(3)把与 \(y\) 相邻的白格内的小方块全部删掉
故考虑对于所有的白格 \(i\) ,拆成两个点 \(i_0\) 和 \(i_1\) ,并连边 \(<i_0,i_1,w_i>\)
对于所有的黑格组(相邻且之间有特殊边的两个黑格)\((x,y)\) ,也建立两个点,第一个点向第二个点连容量为 \(\min(w_x,w_y)\) 的边
这时候我们就有一个比较明显的最小割模型了
即对于需要「至少满足一个」的条件集合进行串联,需要「全部满足」的条件集合进行并联
具体地,如下图:

其中 \(x_1,x_2,x_3\) 表示与 \(x\) 相邻的白格, \(y_1,y_2,y_3\) 同理
以下设上图中 \(x_1,x_2,x_3\) 对应的三条边在第一层, \(\min(w_x,w_y)\) 对应的边在第二层, \(y_1,y_2,y_3\) 对应的三条边在第三层
至于 \(\min(w_x,w_y)\) 的边为什么一定要放在中间,后面会说
我们会发现一个问题:一个白格会属于 \(3\) 个黑格,直接建图会导致不同的黑格组之间互相影响
所以正确的建图方式是:设 \(x\) 在 \(y\) 左边,则要判断黑哥所在行号的奇偶性
若在奇行则 \(S\) 到 \(T\) 的路径上依次限制与 \(x\) 相邻的白格 \(\rightarrow\) 黑格组 \((x,y)\) 本身 \(\rightarrow\) 与 \(y\) 相邻的白格,否则反过来
考虑这样做的正确性:易得这么建图可以使得对于任意一个白格对应的限制边只在一层(第一层或第三层)中出现
如果一个白格 \(i\) 同时属于两个黑格组且位于第一层,且边 \(<i_0,i_1>\) 没有被割掉,那么显然这两个黑格组的第一层限制都必然不会被满足了,这时即使不同的黑格组之间互相影响也不会对最终的答案造成影响。第三层同理
而这时候如果 \(\min(w_x,w_y)\) 不在第二层而在第一层,那么假设这时候 \(i\) 位于第二层,有两个黑格组 \(X\) 和 \(Y\) ,\(X\) 只割掉了第三层,\(Y\) 只割掉了第一层,那么由于保留了边 \(<i_0,i_1>\) 之后 \(X\) 和 \(Y\) 的第二层能互通,故这时源点到汇点有一条 \(S\rightarrow X_1\rightarrow X_2\rightarrow Y_2\rightarrow Y_3\rightarrow T\) 的路径,这时就不合法了
Code
#include <bits/stdc++.h>
template <class T>
inline void read(T &res)
{
res = 0; bool bo = 0; char c;
while (((c = getchar()) < '0' || c > '9') && c != '-');
if (c == '-') bo = 1; else res = c - 48;
while ((c = getchar()) >= '0' && c <= '9')
res = (res << 3) + (res << 1) + (c - 48);
if (bo) res = ~res + 1;
}
template <class T>
inline T Min(const T &a, const T &b) {return a < b ? a : b;}
const int N = 1e5 + 10, M = 3e5 + 5, L = 4e6 + 5, INF = 0x3f3f3f3f;
int n, X[N], Y[N], w[N], ecnt = 1, nxt[L], adj[M], go[L], cap[L], len, que[M],
lev[M], cur[M], S, T, ans;
std::map<int, int> is[N];
int which(int x, int op) {return (x << 1) + op;}
void add_edge(int u, int v, int w)
{
nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v; cap[ecnt] = w;
nxt[++ecnt] = adj[v]; adj[v] = ecnt; go[ecnt] = u; cap[ecnt] = 0;
}
bool bfs()
{
for (int i = S; i <= T; i++) lev[i] = -1, cur[i] = adj[i];
lev[que[len = 1] = S] = 0;
for (int i = 1; i <= len; i++)
{
int u = que[i];
for (int e = adj[u], v = go[e]; e; e = nxt[e], v = go[e])
if (cap[e] && lev[v] == -1)
{
lev[que[++len] = v] = lev[u] + 1;
if (v == T) return 1;
}
}
return 0;
}
int dinic(int u, int flow)
{
if (u == T) return flow;
int res = 0, delta;
for (int &e = cur[u], v = go[e]; e; e = nxt[e], v = go[e])
if (cap[e] && lev[u] < lev[v])
{
delta = dinic(v, Min(cap[e], flow - res));
if (delta)
{
cap[e] -= delta; cap[e ^ 1] += delta;
res += delta; if (res == flow) break;
}
}
if (res < flow) lev[u] = -1;
return res;
}
void add(int i, int j, int op)
{
if (op) add_edge(S, which(j, 0), INF), add_edge(which(j, 1), which(i, 0), INF);
else add_edge(which(i, 1), which(j, 0), INF), add_edge(which(j, 1), T, INF);
}
int main()
{
read(n); read(n); read(n);
for (int i = 1; i <= n; i++)
read(X[i]), read(Y[i]), read(w[i]), is[X[i]][Y[i]] = i;
S = 1; T = n + 1 << 1;
for (int i = 1; i <= n; i++)
{
if (X[i] % 4 != (Y[i] + 1) % 2 * 2 + 1 && X[i] % 4 != Y[i] % 2 * 2)
add_edge(which(i, 0), which(i, 1), w[i]);
if (X[i] % 4 != (Y[i] + 1) % 2 * 2 + 1) continue;
int x = X[i], y = Y[i], j;
if (!(j = is[x + 1][y])) continue;
add_edge(which(i, 0), which(i, 1), Min(w[i], w[j]));
if (j = is[x - 1][y]) add(i, j, y & 1);
if (j = is[x][y - 1]) add(i, j, y & 1);
if (j = is[x][y + 1]) add(i, j, y & 1);
if (j = is[x + 2][y]) add(i, j, !(y & 1));
if (j = is[x + 1][y - 1]) add(i, j, !(y & 1));
if (j = is[x + 1][y + 1]) add(i, j, !(y & 1));
}
while (bfs()) ans += dinic(S, INF);
return std::cout << ans << std::endl, 0;
}
[LOJ#3022][网络流]「CQOI2017」老 C 的方块的更多相关文章
- @loj - 3022@ 「CQOI2017」老 C 的方块
目录 @description@ @solution@ @accepted code@ @details@ @description@ 老 C 是个程序员. 作为一个懒惰的程序员,老 C 经常在电脑上 ...
- 【LOJ】#3020. 「CQOI2017」小 Q 的表格
#3020. 「CQOI2017」小 Q 的表格 这个的话求出来\(g = gcd(a,b)\) 会修改所有gcd为g的位置 我们要求\((g,g)\)这个位置的数一定是\(g^{2}\)的倍数 之后 ...
- [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC
[LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...
- 【LOJ】#2210. 「HNOI2014」江南乐
LOJ#2210. 「HNOI2014」江南乐 感觉是要推sg函数 发现\(\lfloor \frac{N}{i}\rfloor\)只有\(O(\sqrt{N})\)种取值 考虑把这些取值都拿出来,能 ...
- 【LOJ】#3098. 「SNOI2019」纸牌
LOJ#3098. 「SNOI2019」纸牌 显然选三个以上的连续牌可以把他们拆分成三个三张相等的 于是可以压\((j,k)\)为有\(j\)个连续两个的,有\(k\)个连续一个的 如果当前有\(i\ ...
- 【LOJ】#3103. 「JSOI2019」节日庆典
LOJ#3103. 「JSOI2019」节日庆典 能当最小位置的值一定是一个最小后缀,而有用的最小后缀不超过\(\log n\)个 为什么不超过\(\log n\)个,看了一下zsy的博客.. 假如\ ...
- 【LOJ】#3102. 「JSOI2019」神经网络
LOJ#3102. 「JSOI2019」神经网络 首先我们容易发现就是把树拆成若干条链,然后要求这些链排在一个环上,同一棵树的链不相邻 把树拆成链可以用一个简单(但是需要复杂的分类讨论)的树背包实现 ...
- 【LOJ】#3101. 「JSOI2019」精准预测
LOJ#3101. 「JSOI2019」精准预测 设0是生,1是死,按2-sat连边那么第一种情况是\((t,x,1) \rightarrow (t + 1,y,1)\),\((t + 1,y, 0) ...
- 【LOJ】#3097. 「SNOI2019」通信
LOJ#3097. 「SNOI2019」通信 费用流,有点玄妙 显然按照最小路径覆盖那题的建图思路,把一个点拆成两种点,一种是从这个点出去,标成\(x_{i}\),一种是输入到这个点,使得两条路径合成 ...
随机推荐
- Java语言中使用OpenMP
从去年年中,开始学习Java,主要是维护公司用Java编写的服务器软件.目前,该服务器软件遇到一个问题,在下载大文件时,如果同时下载的用户很多, 服务器软件工作会出现异常,有的用户无法下载.服务器硬件 ...
- CUP计算资源争抢通过IIS启用处理器关联解决
由于业务的复杂性,我们在客户环境部署的时候,采用的是预装好在一台机器然后再把机器安装到客户环境,所以为了简单方便,我们把所有的服务都安装到一台机器上面了. 在正常的使用过程中是没有任何问题的.但是当有 ...
- hibernate映射-继承映射
对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate的继承映射可以理解成持久化类之间的继承关系.例如:人和学生之间的关系.学生继承人,可以认为学生是一个特殊的人,如果对人进 ...
- echart环形图制作及出现的一些问题总结
环形图的形成其实就是echarts中的饼图pie,控制饼图的内圈半径和外圈半径来形成环形的效果!下面记录的问题是在开发中出现发现的,因为在网上找到了利用阴影来做下面的图: 说明: 由于代码比较长,不能 ...
- 【题解】CTSC1999家园(网络流)
CTSC1999家园 建模方法类似我NOI2019网络同步赛我的T1写法[[题解]NOI2019Route](70分) 问题的焦点是:空间时间载具. 考虑如何击破时间限制,可以对每个点关于每个时刻建立 ...
- $Loj10155$ 数字转换(求树的最长链) 树形$DP$
loj Description 如果一个数x的/约数和/y(不包括他本身)比他本身小,那么x可以变成y,y 也可以变成x.限定所有数字变换在不超过n的正整数范围内进行,求不断进行数字变换且不出现重复数 ...
- 跌宕起伏的java帝国史,剖析谷歌甲骨文长达8年的版权战争
这篇博文是我在B站上发的一个科普java的视频文案整理,本来发过一次了,但是有几种不严谨的地方只能删掉重新发了一下,内容如标题,感兴趣的码农朋友可以观看视频的版本,欢迎提提意见啥的,感谢~https: ...
- 大数据学习之路-phoenix
1.phoenix安装 ------------------ 1.安装phoenix a)下载apache-phoenix-4.10.0-HBase-1.2-bin.tar.gz 下载网址:htt ...
- spring 与mybatis 整合
步骤: pom文件添加依赖 创建包结构 添加application.yml, 配置数据库信息 使用mybatis-gennerator 生成三个文件 实体类 接口类 xml 文件 错误信息 xml 绑 ...
- 利用log4net创建日志文件时过滤日志,这是坑还是?
前言 网上貌似没有太多关于log4net过滤日志的资料,在研究过程中发现一点小问题,这里做下记录,希望对后续有用到的童鞋起到一丢丢帮助作用. log4net日志过滤 由于是在.NET Core中使用, ...