bzoj 4823: [Cqoi2017]老C的方块 [最小割]
4823: [Cqoi2017]老C的方块
题意:
鬼畜方块游戏不解释...
有些特殊边,有些四个方块组成的图形,方块有代价,删掉一些方块使得没有图形,最小化代价。
比较明显的最小割,一个图形中必须删掉一个方块。
我的想法是方块拆点然后用INF连起来。
但是你不能随便连啊,否则可能会出现一些原来没有的限制。
要找到一个连边的顺序!也就是如何分层
画一画发现是可以做到的,然后建图就行了。
我是一层一层建的...
然后一开始忘记考虑一种图形WA了两次...
总共花了3个多小时...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int N = 2e5+5, M = 2e6+5, INF = 1e9+5;
inline int read() {
char c=getchar(); int x=0,f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
}
int m, n, k, s, t;
struct meow{int x, y, w;} a[N];
map<int, int> g[100005];
struct edge{int v, ne, c, f;} e[M];
int cnt=1, h[N];
inline void ins(int u, int v, int c) {
e[++cnt] = (edge){v, h[u], c, 0}; h[u] = cnt;
e[++cnt] = (edge){u, h[v], 0, 0}; h[v] = cnt;
}
int start(int x, int y) {
if((x-2)%4 == 0) {
if(!(y&1)) return 1;
else return 0;
}
if((x+1)%4 == 0) {
if(y&1) return 2;
else return 0;
}
return 0;
}
inline void link(int u, int v) { ins(u+k, v, INF); }
int t1[N], t2[N];
void build() {
s = 0; t = k+k+1;
for(int i=1; i<=k; i++) ins(i, i+k, a[i].w);
int v;
int *mark = t1, *mark2 = t2;
for(int i=1; i<=k; i++) {
int x = a[i].x, y = a[i].y, p = start(x, y);
if(!p) continue;
ins(s, i, INF); //printf("start (%d, %d) %d\n", x, y, p);
if(p == 1) {
if(g[x].count(y+1)) v = g[x][y+1], link(i, v), mark[v] = 1;
if(g[x].count(y-1)) v = g[x][y-1], link(i, v), mark[v] = 1;
if(g[x+1].count(y)) v = g[x+1][y], link(i, v), mark[v] = 2;
} else {
if(g[x].count(y+1)) v = g[x][y+1], link(i, v), mark[v] = 2;
if(g[x].count(y-1)) v = g[x][y-1], link(i, v), mark[v] = 2;
if(g[x-1].count(y)) v = g[x-1][y], link(i, v), mark[v] = 1;
}
}
swap(mark, mark2);
for(int i=1; i<=k; i++) if(mark2[i]) {
int x = a[i].x, y = a[i].y, p = mark2[i]; mark2[i] = 0;
if(p == 1 && g[x-1].count(y)) v = g[x-1][y], link(i, v), mark[v] = 1;
if(p == 2 && g[x+1].count(y)) v = g[x+1][y], link(i, v), mark[v] = 2;
}
swap(mark, mark2);
for(int i=1; i<=k; i++) if(mark2[i]) {
int x = a[i].x, y = a[i].y, p = mark2[i]; mark2[i] = 0;
if(g[x].count(y+1)) v = g[x][y+1], link(i, v), mark[v] = 1;
if(g[x].count(y-1)) v = g[x][y-1], link(i, v), mark[v] = 1;
if(p == 1 && g[x-1].count(y)) v = g[x-1][y], link(i, v), mark[v] = 1;
if(p == 2 && g[x+1].count(y)) v = g[x+1][y], link(i, v), mark[v] = 1;
}
for(int i=1; i<=k; i++) if(mark[i]) ins(i+k, t, INF);
}
namespace mf {
int q[N], head, tail, vis[N], d[N];
bool bfs() {
memset(vis, 0, sizeof(vis));
head = tail = 1;
q[tail++] = s; d[s] = 0; vis[s] = 1;
while(head != tail) {
int u = q[head++];
for(int i=h[u];i;i=e[i].ne)
if(!vis[e[i].v] && e[i].c > e[i].f) {
int v = e[i].v;
vis[v] = 1; d[v] = d[u]+1;
q[tail++] = v;
if(v == t) return true;
}
}
return false;
}
int cur[N];
int dfs(int u, int a) {
if(u == t || a == 0) return a;
int flow = 0, f;
for(int &i=cur[u];i;i=e[i].ne)
if(d[e[i].v] == d[u]+1 && (f = dfs(e[i].v, min(a, e[i].c - e[i].f)) ) >0 ) {
flow += f;
e[i].f += f;
e[i^1].f -= f;
a -= f;
if(a == 0) break;
}
if(a) d[u] = -1;
return flow;
}
int dinic() {
int flow = 0;
while(bfs()) {
for(int i=s; i<=t; i++) cur[i] = h[i];
flow += dfs(s, INF);
}
return flow;
}
}
int main() {
freopen("in", "r", stdin);
m=read(); n=read(); k=read();
for(int i=1; i<=k; i++) a[i].x = read(), a[i].y = read(), a[i].w = read(), g[a[i].x][a[i].y] = i;
build();
int ans = mf::dinic();
printf("%d\n", ans);
}
bzoj 4823: [Cqoi2017]老C的方块 [最小割]的更多相关文章
- bzoj4823: [Cqoi2017]老C的方块(最小割)
4823: [Cqoi2017]老C的方块 题目:传送门 题解: 毒瘤题ORZ.... 太菜了看出来是最小割啥边都不会建...狂%大佬强强强 黑白染色?不!是四个色一起染,四层图跑最小割... 很 ...
- BZOJ 4823: [Cqoi2017]老C的方块
分析: 我觉得我的网络流白学了...QAQ... 其实数据范围本是无法用网络流跑过去的,然而出题者想让他跑过去,也就跑过去了... 看到题目其实感觉很麻烦,不知道从哪里入手,那么仔细观察所给出的有用信 ...
- bzoj 4823 [Cqoi2017]老C的方块——网络流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823 一个不合法方案其实就是蓝线的两边格子一定选.剩下两部分四相邻格子里各选一个. 所以这个 ...
- BZOJ 4823 [Cqoi2017]老C的方块 ——网络流
lrd的题解:http://www.cnblogs.com/liu-runda/p/6695139.html 我还是太菜了.以后遇到这种题目应该分析分析性质的. 网络流复杂度真是$O(玄学)$ #in ...
- bzoj 4823: [Cqoi2017]老C的方块【最大权闭合子图】
参考:https://www.cnblogs.com/neighthorn/p/6705785.html 并不是黑白染色而是三色染色(还有四色的,不过是一个意思 仔细观察一下不合法情况,可以发现都是特 ...
- bzoj 4823 & 洛谷 P3756 老C的方块 —— 最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823 https://www.luogu.org/problemnew/show/P3756 ...
- 【BZOJ4823】[CQOI2017]老C的方块(网络流)
[BZOJ4823][CQOI2017]老C的方块(网络流) 题面 BZOJ 题解 首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑. 为了和其他格子区分,我们把两侧的这两个格子 ...
- BZOJ 4823 Luogu P3756 [CQOI2017]老C的方块 (网络流、最小割)
题目链接 (Luogu) https://www.luogu.org/problem/P3756 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id= ...
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
随机推荐
- Number Sequence(快速幂矩阵)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 Number Sequence Time Limit: 2000/1000 MS (Java/O ...
- Dockerfile中CMD和ENTRYPOINT的区别
当启动一个容器时,CMD和ENTRYPOINT都可以用来执行启动命令.但它们的具体用法还是有一些区别: 1. Dockerfile必须至少指定CMD或者ENTRYPOINT其中的一个. 2. ENTR ...
- 安装Ubuntu16.04失败
原本安装的是Ubuntu14,但是在使用caffe时总是出错,所以干脆将Ubuntu从14升级到16,结果整出一堆麻烦.在解决这些麻烦的过程也学习了不少系统启动的细节.印证了那句话"如何没有 ...
- 获取屏幕宽高度与可视区域宽高度(availWidth、clientWidth、width、innerWidth)
经常会遇到需要获取屏幕宽度.高度,可视区域宽度.高度等问题,也就常跟这几个打交道,一不小心,还真爱弄混淆了. 先来列举下这几个吧: screen.availHeight.screen.availWid ...
- PageRank_网页排名_MapReduceJava代码实现思路
PageRank 1. 概念 2. 原理 3. java代码实现思路 1.定义收敛标准 每次算出新的pr-oldpr=差值 ,所有页面的差值累加 ,除以pagecou ...
- asp.net -mvc框架复习(8)-实现用户登录模型部分的编写
1.配置文件添加数据库连接字符串(web.config) 2.编写通用数据库访问类 (1)引入命名空间 using System.Configuration; (2) 定义连接字符串 (3)编写完成 ...
- 2.supervisor实时监控程序存活状态
1.supervisor是一款python开发的一个client/server服务,是一款进程管理工具,支持linux/unix系统,但是不支持windows系统. 它可以很方便的监听.启动.停止.重 ...
- 详解javascript中的闭包
全局变量与局部变量 在说闭包之前先说明全局变量与局部变量 全局变量:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义. 局部变量:使用var关键字定义 全局变量/局部变 ...
- 图表工具--- ECharts.js学习(一) 简单入门
ECharts.js学习(一) 在项目开发的时候,在前端的数据需要用图表的形式展示.网上搜索了一下,发现有几种统计图库.具体有哪几种可以看: 前端开发者常用的9个JavaScript图表库 EChar ...
- 关于多台机器之前session共享,sessionState mode="StateServer" 问题的困扰
.net 多台机器共享session是很老的技术,一直很少用到session. 最近就出现了一个问题:三台前端,其中一台保存的session值死活不对,一样的环境,一样的配置文件,就是和另外两台获得的 ...