【BZOJ4823】[CQOI2017]老C的方块(网络流)
【BZOJ4823】[CQOI2017]老C的方块(网络流)
题面
题解
首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑。
为了和其他格子区分,我们把两侧的这两个格子染成灰色。
于是一个不合法的状态就是两个相邻的灰色点如果还和一个其他的点相连就是非法的。
我们先把黑白点分开,源点连向黑点,汇点连向白点,边权是删去这个点的代价。
因为灰点可以两两配对,非两两配对之间的没有影响,然后所有黑点连向对应的灰点,另一半灰点连向对应的白点。而要删去一组不合法的要么删去一个灰点,要么删去所有黑点或者所有白点,而连向源汇已经处理了删去所有黑点或者白点,所以只需要考虑删去一个灰点,显然删哪个都是一样的所以两个匹配的灰点之间连一条权值为两个点权值较小值的边。
这样子最小割就是答案。
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define MAX 100100
const int inf=2e9;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next,w;}e[MAX*20];
int h[MAX],cnt=2;
inline void Add(int u,int v,int w)
{
e[cnt]=(Line){v,h[u],w};h[u]=cnt++;
e[cnt]=(Line){u,h[v],0};h[v]=cnt++;
}
int S,T,cur[MAX],level[MAX];
queue<int> Q;
bool bfs()
{
for(int i=S;i<=T;++i)level[i]=0;
Q.push(S);level[S]=1;
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=h[u];i;i=e[i].next)
if(e[i].w&&!level[e[i].v])
level[e[i].v]=level[u]+1,Q.push(e[i].v);
}
return level[T];
}
int dfs(int u,int flow)
{
if(u==T||!flow)return flow;
int ret=0;
for(int &i=cur[u];i;i=e[i].next)
{
int v=e[i].v,d;
if(e[i].w&&level[v]==level[u]+1)
{
d=dfs(v,min(flow,e[i].w));
ret+=d;flow-=d;
e[i].w-=d;e[i^1].w+=d;
if(!flow)break;
}
}
if(!ret)level[u]=0;
return ret;
}
int Dinic()
{
int ret=0;
while(bfs())
{
for(int i=S;i<=T;++i)cur[i]=h[i];
ret+=dfs(S,inf);
}
return ret;
}
map<pair<int,int>,int> M;
int col[MAX];
int d[4][2]={1,0,0,1,-1,0,0,-1};
int C,R,n,X[MAX],Y[MAX],W[MAX];
bool check(int x,int y)
{
if(x&1)return y%4==1||y%4==2;
else return y%4==3||y%4==0;
}
int main()
{
R=read();C=read();n=read();
for(int i=1;i<=n;++i)
{
Y[i]=read();X[i]=read();W[i]=read();
M[make_pair(X[i],Y[i])]=i;
if((X[i]+Y[i]+1)&1)col[i]=check(X[i],Y[i])?3:1;
else col[i]=check(X[i],Y[i])?2:0;
}
S=0;T=n+1;
for(int i=1;i<=n;++i)
if(col[i]==0)Add(i,T,W[i]);
else if(col[i]==1)Add(S,i,W[i]);
else if(col[i]==2)
for(int j=0;j<4;++j)
{
int x=X[i]+d[j][0],y=Y[i]+d[j][1];
if(M.find(make_pair(x,y))==M.end())continue;
int d=M[make_pair(x,y)];
if(col[d]==1)Add(d,i,inf);
else if(col[d]==3)Add(i,d,min(W[d],W[i]));
}
else if(col[i]==3)
for(int j=0;j<4;++j)
{
int x=X[i]+d[j][0],y=Y[i]+d[j][1];
if(M.find(make_pair(x,y))==M.end())continue;
int d=M[make_pair(x,y)];
if(col[d]==0)Add(i,d,inf);
}
printf("%d\n",Dinic());
return 0;
}
【BZOJ4823】[CQOI2017]老C的方块(网络流)的更多相关文章
- bzoj4823: [Cqoi2017]老C的方块(最小割)
4823: [Cqoi2017]老C的方块 题目:传送门 题解: 毒瘤题ORZ.... 太菜了看出来是最小割啥边都不会建...狂%大佬强强强 黑白染色?不!是四个色一起染,四层图跑最小割... 很 ...
- BZOJ4823 CQOI2017老C的方块(最小割)
如果将其转化为一个更一般的问题即二分图带权最小单边点覆盖(最小控制集)感觉是非常npc的.考虑原题给的一大堆东西究竟有什么奇怪的性质. 容易发现如果与特殊边相邻的两格子都放了方块,并且这两个格子都各有 ...
- BZOJ4823 [Cqoi2017]老C的方块 【最小割】
题目 老C是个程序员. 作为一个懒惰的程序员,老C经常在电脑上玩方块游戏消磨时间.游戏被限定在一个由小方格排成的R行C列网格上,如果两个小方格有公共的边,就称它们是相邻的,而且有些相邻的小方格之间的公 ...
- [bzoj4823][Cqoi2017]老C的方块
来自FallDream的博客,未经允许,请勿转载,谢谢. 挺有意思的一道题.... 看完题面比较明确是最小割,考虑怎么建图 想了比较久 突破口应该是题目中那张奇怪的图 观察这个奇怪的图和方块,很容易发 ...
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
- [CQOI2017]老C的方块 网络流
---题面--- 题解: 做这题做了好久,,,换了4种建图QAQ 首先我们观察弃疗的形状,可以发现有一个特点,那就是都以一个固定不变的特殊边为中心的,如果我们将特殊边两边的方块分别称为s块和t块, 那 ...
- BZOJ 4823 [Cqoi2017]老C的方块 ——网络流
lrd的题解:http://www.cnblogs.com/liu-runda/p/6695139.html 我还是太菜了.以后遇到这种题目应该分析分析性质的. 网络流复杂度真是$O(玄学)$ #in ...
- 洛谷$P3756\ [CQOI2017]$老$C$的方块 网络流
正解:网络流 解题报告: 传送门$QwQ$ 看到不能出现给定的讨厌的图形,简单来说就,特殊边两侧的方格不能同时再连方格. 所以如果出现,就相当于是四种方案?就分别炸四个格子. 然后冷静分析一波之后发现 ...
- bzoj 4823 [Cqoi2017]老C的方块——网络流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823 一个不合法方案其实就是蓝线的两边格子一定选.剩下两部分四相邻格子里各选一个. 所以这个 ...
- BZOJ 4823 Luogu P3756 [CQOI2017]老C的方块 (网络流、最小割)
题目链接 (Luogu) https://www.luogu.org/problem/P3756 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id= ...
随机推荐
- (day67)组件、组件化、组件传参、JS补充(命名转换、for in 、数据转换)、css取消选中和模拟小手
目录 一.初识组件 (一)概念 (二)特点 二.组件的分类 (一)根组件 (二)局部组件 (三)全局组件 二.数据组件化 三.组件的传参 (一)父传子 (二)子传父 四.JS补充 (一)与html命名 ...
- 洛谷 SP263 Period
洛谷 SP263 Period 题目描述 For each prefix of a given string S* with N* characters (each character has an ...
- [译]Vulkan教程(25)描述符布局和buffer
[译]Vulkan教程(25)描述符布局和buffer Descriptor layout and buffer 描述符布局和buffer Introduction 入门 We're now able ...
- java之instanceof操作符
a intanceof A:判断a是否是类A的的一个实例,返回值为boolean public class Person extends Object{} public class Student e ...
- 【Oracle】datafile的resize大小确认方法
在对Oracle的表进行删除操作的时候,虽然数据被清空了,但是物理上占用的空间却没有被释放掉,这有可能使我们的DB服务器的物理存储始终在增长. 我们在删除用户,表的同时也要对datafile文件进行r ...
- App 自动化框架设计思路
最近在整理和学习Appium+Java 自动化框架,对APP自动化框架的部分设想参考了一些文章,先进行整理下: 框架的思路一: 思考引入:https://www.cnblogs.com/yunfeio ...
- 急速下载pandas
使用国内源进行下载: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua ...
- js中scroll滚动相关
js中scroll滚动相关 scroll,滚动,一般讨论的是网页整体与浏览器之间的关系. 一.元素相关 属性/方法 解释 element.scrollHeight 返回元素的整体高度. element ...
- 应届生offer指南
通用技术 1.一般公司对应届生都要考察编程能力,所以应聘之前先刷刷题.我做面试官出的编程题两年没有变过.就是这道
- 面试再问ThreadLocal,别说你不会
转载自:公众号<Java知音> ThreadLocal是什么 以前面试的时候问到ThreadLocal总是一脸懵逼,只知道有这个哥们,不了解他是用来做什么的,更不清楚他的原理了.表面上看他 ...