~~~题面~~~

题解:

做这题做了好久,,,换了4种建图QAQ

首先我们观察弃疗的形状,可以发现有一个特点,那就是都以一个固定不变的特殊边为中心的,如果我们将特殊边两边的方块分别称为s块和t块,

那么我们可以观察到,s块和t块永远是在中心位置,而其他两块则是紧邻s块和t块,一边一个。

所以我们要考虑将这个图像用一根线串起来,这样跑最小割才能割最小的边,

那么如何做到一条边割几个图形呢?

首先我们观察到一个非st方块本来就可以属于多个图形,因此也会有多条连边,因此我们只需要对每个方块拆点,限制其只能割一次就可以了。

一开始我选择的连图方式是:

以特殊边左边为s块,右边为t块,s连向s块,t块连向t(s块和t块名字来源),s块连向四周的非t块,t块四周的非s块连向它,s块四周的非t块连向t块四周的非s块。

但这样为什么这样不行呢?

我们可以观察到这样一种情况,

可以发现,右边的小圆圈同时处在s块和t块周围,那么由于扮演了两个角色,这就有可能导致右边的s块的流量流到左边的t块里,于是就出现了不合法情况。

…………

遂交换偶行的s块和t块。

可以发现,右边的s块和左边的t块构成了一个不合法图形,那么这是为什么?

显然是上面反过来的t块和s块在勾桥搭线。。。。

那怎么办?

我们再观察一下图形。既然所有图形都是以s块和t块为中心,那么这两块显然是更加稳定的,因此我们不再用其他块作为中转块,而是采用以s块和t块为中转。

即:

s ---> s块周围的块 ----> s块 ---> t块 ---> t块周围的块

经验证,可以满足要求。

我是强行暴力人工分类讨论建图的。。。因此代码很长,建图就有60行。。。。

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define inf 2139062143
#define getchar() *o++
#define AC 200100
#define ac 1700000 char READ[], *o = READ;
int n, x, ans, s, t, addflow, X, Y;
int last[AC], good[AC], have[AC], c[AC], power[AC];
int q[AC], head, tail;
int date[ac], Next[ac], haveflow[ac], Head[AC], tot = ; struct point{
int x, y;
}p[AC]; bool operator < (point a, point b)
{
if(a.x != b.x) return a.x < b.x;
else return a.y < b.y;
} map<point, int> m; inline int read()
{
int x=;char c=getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x=x*+c-'',c=getchar();
return x;
} inline void add(int f, int w, int S)
{
date[++tot] = w, Next[tot] = Head[f], haveflow[tot] = S, Head[f] = tot;
date[++tot] = f, Next[tot] = Head[w],/* haveflow[tot] = 0,*/ Head[w] = tot;
// printf("%d ---> %d %d\n", f, w, S);
} void pre()
{
X = read(), Y = read(), n = read();
s = n * + , t = s + ;
for(R i=;i<=n;i++)
{
p[i].y = read(), p[i].x = read(), power[i] = read();//注意行列是反的!
m[p[i]] = i;//编号
}
} void build()//暴力枚举加边
{
int x, y;
for(R i=;i<=n;i++)//枚举方块,只连出边
{
add(i, n + i, power[i]);//拆点连边
x = p[i].x, y = p[i].y;
if(x % )//按奇偶行分类
{
if(y % )//按奇偶列分类(可能为s or t右)
{//因为2 = 2 * 1, 6 = 2 * 3 .... 所以有余数就说明是s
if(((y + ) / ) % )//有余数所以是s
{//跟旁边的t连上
if(m[(point){x, y + }]) add(i + n, m[(point){x, y + }], inf);
}
else add(i + n, t, inf);//不然就要连向t了
}
else//不然就是s左的 or t
{
if((y / ) % )
{
if(m[(point){x, y + }]) add(i + n, m[(point){x, y + }], inf);//如果有余数说明是t
if(m[(point){x + , y}]) add(i + n, m[(point){x + , y}], inf);
if(m[(point){x - , y}]) add(i + n, m[(point){x - , y}], inf);
}
else//不然属于s周围的
{
if(m[(point){x, y + }]) add(i + n, m[(point){x, y + }], inf);
if(m[(point){x + , y}]) add(i + n, m[(point){x + , y}], inf);
if(m[(point){x - , y}]) add(i + n, m[(point){x - , y}], inf);
add(s, i, inf);//注意s周围的要连s
}
}
}
else //偶行
{
if(y % )//奇列,t or s右
{
if(((y + ) / ) % )//如果有余数说明是s右
{
if(m[(point){x, y - }]) add(i + n, m[(point){x, y - }], inf);
if(m[(point){x + , y}]) add(i + n, m[(point){x + , y}], inf);
if(m[(point){x - , y}]) add(i + n, m[(point){x - , y}], inf);
add(s, i, inf);
}
else
{
if(m[(point){x, y - }]) add(i + n, m[(point){x, y - }], inf);//如果有余数说明是t
if(m[(point){x + , y}]) add(i + n, m[(point){x + , y}], inf);
if(m[(point){x - , y}]) add(i + n, m[(point){x - , y}], inf);
}
}
else//t左 or s
{
if((y / ) % ) add(i + n, t, inf);//如果有余数的话,说明是t左
else//不然就是s
if(m[(point){x, y - }]) add(i + n, m[(point){x, y - }], inf);
}//注意加了n才是出发点
}
}
} void bfs()
{
int x, now;
c[t] = , x = t, q[++tail] = t;
while(head < tail)
{
x = q[++head];
for(R i=Head[x]; i; i=Next[i])
{
now = date[i];
if(haveflow[i^] && !c[now])
{
++have[c[now] = c[x] + ];
q[++tail] = now;
}
}
}
memcpy(good, Head, sizeof(Head));
} inline void aru()
{
while(x != s)
{
haveflow[last[x]] -= addflow;
haveflow[last[x] ^ ] += addflow;
x = date[last[x] ^ ];
}
ans += addflow;
} void isap()
{
int now; bool done;
addflow = inf, x = s;
while(c[s] != )
{
if(x == t) aru(), addflow = inf;
done = false;
for(R i =good[x]; i ;i =Next[i])
{
now = date[i];
if(haveflow[i] && c[now] == c[x] -)
{
addflow = min(addflow, haveflow[i]);
last[now] = i;
good[x] = i;
done = true;
x = now;
break;
}
}
if(!done)
{
int go = ;
for(R i=Head[x]; i ;i=Next[i])
{
now = date[i];
if(haveflow[i] && c[now]) go = min(go, c[now]);
}
good[x] = Head[x];
if(!(--have[c[x]])) break;
++have[c[x] = go + ];
if(x != s) x = date[last[x] ^ ];
}
}
printf("%d\n", ans);
} int main()
{
// freopen("in.in","r",stdin);
fread(READ, , , stdin);
pre();
build();
bfs();
isap();
// fclose(stdin);
return ;
}

[CQOI2017]老C的方块 网络流的更多相关文章

  1. BZOJ 4823 [Cqoi2017]老C的方块 ——网络流

    lrd的题解:http://www.cnblogs.com/liu-runda/p/6695139.html 我还是太菜了.以后遇到这种题目应该分析分析性质的. 网络流复杂度真是$O(玄学)$ #in ...

  2. 洛谷$P3756\ [CQOI2017]$老$C$的方块 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 看到不能出现给定的讨厌的图形,简单来说就,特殊边两侧的方格不能同时再连方格. 所以如果出现,就相当于是四种方案?就分别炸四个格子. 然后冷静分析一波之后发现 ...

  3. bzoj 4823 [Cqoi2017]老C的方块——网络流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823 一个不合法方案其实就是蓝线的两边格子一定选.剩下两部分四相邻格子里各选一个. 所以这个 ...

  4. BZOJ 4823 Luogu P3756 [CQOI2017]老C的方块 (网络流、最小割)

    题目链接 (Luogu) https://www.luogu.org/problem/P3756 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id= ...

  5. 【BZOJ4823】[CQOI2017]老C的方块(网络流)

    [BZOJ4823][CQOI2017]老C的方块(网络流) 题面 BZOJ 题解 首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑. 为了和其他格子区分,我们把两侧的这两个格子 ...

  6. bzoj 4823: [Cqoi2017]老C的方块 [最小割]

    4823: [Cqoi2017]老C的方块 题意: 鬼畜方块游戏不解释... 有些特殊边,有些四个方块组成的图形,方块有代价,删掉一些方块使得没有图形,最小化代价. 比较明显的最小割,一个图形中必须删 ...

  7. bzoj4823: [Cqoi2017]老C的方块(最小割)

    4823: [Cqoi2017]老C的方块 题目:传送门 题解: 毒瘤题ORZ.... 太菜了看出来是最小割啥边都不会建...狂%大佬强强强   黑白染色?不!是四个色一起染,四层图跑最小割... 很 ...

  8. 【题解】CQOI2017老C的方块

    网络流真的是一种神奇的算法.在一张图上面求感觉高度自动化的方案一般而言好像都是网络流的主阵地.讲真一开始看到这道题也有点懵,题面很长,感觉很难的样子.不过,仔细阅读了题意之后明白了:我们所要做的就是要 ...

  9. BZOJ 4823: [Cqoi2017]老C的方块

    分析: 我觉得我的网络流白学了...QAQ... 其实数据范围本是无法用网络流跑过去的,然而出题者想让他跑过去,也就跑过去了... 看到题目其实感觉很麻烦,不知道从哪里入手,那么仔细观察所给出的有用信 ...

随机推荐

  1. ROS Twist和Odometry消息类型使用(Python)

    消息类型: 1. Twist - 线速度角速度 通常被用于发送到/cmd_vel话题,被base controller节点监听,控制机器人运动 geometry_msgs/Twist geometry ...

  2. python 3.6 setup

    1.添加python3.6安装包,并且安装 sudo apt-get install software-properties-common 2.下载python3.6 sudo add-apt-rep ...

  3. Kubernetes网络方案的三大类别和六个场景

    欢迎访问网易云社区,了解更多网易技术产品运营经验. 本文章根据网易云资深解决方案架构师 王必成在云原生用户大会上的分享整理. 今天我将分享个人对于网络方案的理解,以及网易云在交付 Kubernetes ...

  4. mysql源码

    从代码的角度来说,没有丝毫设计感,尤其是优化器部分.不过那些是常年累积的原因,一些新加较独立的部分,设计的就很舒服,真正的面向对象做法.

  5. 92套AE抖音快闪模板(精品)

    包含很多场景和类型,直接用即可,下载地址:百度网盘,https://pan.baidu.com/s/1bRFql1zFWyfpTAwa6MhuPA 内容截图:    

  6. 阿里云服务器Linux系统安装配置ElasticSearch搜索引擎

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...

  7. Qt 报错onecoreuap\inetcore\urlmon\zones\zoneidentifier.cxx(359)\urlmon.dll!00007FF9D9FA5B50:

    具体报错内容 onecoreuap\inetcore\urlmon\zones\zoneidentifier.cxx(359)\urlmon.dll!00007FF9D9FA5B50: (caller ...

  8. 180709-Java实现获取本机Ip的工具类

    180709-Java实现获取本机Ip的工具类 获取本机Ip算是比较常见的一个需求场景了,比如业务报警,可能就会带上出问题的机器IP,方便直接上去看日志定位问题,那么问题来了,如何获取机器IP呢? I ...

  9. Jmeter 接口自动化执行报错 无法找到类或者类的方法

    写好的自动化测试脚本在PC以及mac book 都执行正确,但是放到linux集成环境时就一直报错,报错类似如下 [jmeter] // Debug: eval: nameSpace = NameSp ...

  10. 【RL系列】Multi-Armed Bandit笔记补充(一)

    在此之前,请先阅读上一篇文章:[RL系列]Multi-Armed Bandit笔记 本篇的主题就如标题所示,只是上一篇文章的补充,主要关注两道来自于Reinforcement Learning: An ...