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

题面

BZOJ

题解

首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑。

为了和其他格子区分,我们把两侧的这两个格子染成灰色。

于是一个不合法的状态就是两个相邻的灰色点如果还和一个其他的点相连就是非法的。

我们先把黑白点分开,源点连向黑点,汇点连向白点,边权是删去这个点的代价。

因为灰点可以两两配对,非两两配对之间的没有影响,然后所有黑点连向对应的灰点,另一半灰点连向对应的白点。而要删去一组不合法的要么删去一个灰点,要么删去所有黑点或者所有白点,而连向源汇已经处理了删去所有黑点或者白点,所以只需要考虑删去一个灰点,显然删哪个都是一样的所以两个匹配的灰点之间连一条权值为两个点权值较小值的边。

这样子最小割就是答案。

#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的方块(网络流)的更多相关文章

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

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

  2. BZOJ4823 CQOI2017老C的方块(最小割)

    如果将其转化为一个更一般的问题即二分图带权最小单边点覆盖(最小控制集)感觉是非常npc的.考虑原题给的一大堆东西究竟有什么奇怪的性质. 容易发现如果与特殊边相邻的两格子都放了方块,并且这两个格子都各有 ...

  3. BZOJ4823 [Cqoi2017]老C的方块 【最小割】

    题目 老C是个程序员. 作为一个懒惰的程序员,老C经常在电脑上玩方块游戏消磨时间.游戏被限定在一个由小方格排成的R行C列网格上,如果两个小方格有公共的边,就称它们是相邻的,而且有些相邻的小方格之间的公 ...

  4. [bzoj4823][Cqoi2017]老C的方块

    来自FallDream的博客,未经允许,请勿转载,谢谢. 挺有意思的一道题.... 看完题面比较明确是最小割,考虑怎么建图 想了比较久 突破口应该是题目中那张奇怪的图 观察这个奇怪的图和方块,很容易发 ...

  5. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  6. [CQOI2017]老C的方块 网络流

    ---题面--- 题解: 做这题做了好久,,,换了4种建图QAQ 首先我们观察弃疗的形状,可以发现有一个特点,那就是都以一个固定不变的特殊边为中心的,如果我们将特殊边两边的方块分别称为s块和t块, 那 ...

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

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

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

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

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

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

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

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

随机推荐

  1. 给OPi Zero Plus添加USB启动功能

    为使OPi Zero Plus支持U盘启动,需要在板载的SPI Flash当中刷入uboot.在这个过程当中绕了很多弯路,特此记录 最终操作步骤见文末 网上的教程仅使用sudo modprobe sp ...

  2. vsftpd服务的基本配置

    本文环境:CentOS 7 简介 FTP(文件传输协议,File Transfer Protocol)是最古老的协议之一,诞生于1971年,距今已经半个世纪了,它的目的是在不同计算机之间传输文件(实现 ...

  3. (转)GitHub Desktop 拉取 GitHub上 Tag 版本代码

    转自:GitHub Desktop 拉取 GitHub上 Tag 版本代码 一直在使用 GitHub Desktop 图形化 git 管理工具,统一项目框架版本时需要切换到ThinkPHP Tag 分 ...

  4. 【重学Git】基础命令篇

    1.git commit :在提交树中增加一个提交节点,注意:分支是指向提交节点的. 2.git branch newImage : 表示创建一个名为newImage的分支. 3.git checko ...

  5. Cobalt Strike系列教程第一章:简介与安装

    Cobalt Strike是一款超级好用的渗透测试工具,拥有多种协议主机上线方式,集成了提权,凭据导出,端口转发,socket代理,office攻击,文件捆绑,钓鱼等多种功能.同时,Cobalt St ...

  6. 微服务与Spring Cloud基本概念、Spring Cloud版本命名方式与版本选择

    微服务是什么?Spring Cloud是什么?Spring Cloud版本命名方式?Spring Cloud版本选择? 一.微服务是什么 微服务是一种架构风格,是一种将单体应用开发为一组小型服务的方法 ...

  7. SQL,case ziduan when ziduan_value then 'result'

    case a.sex when 0 then '女' when 1 then '男' else '其他' end as sex 当a表的性别字段的value为0时将查询的value转换成 '女',当字 ...

  8. C# 中使用 Redis 简单存储

    Redis 是一个开源的使用 ANSI C语言编写的支持网络.可基于内存也可持久化的日志型.Key-Value 数据库. 常用它来存储缓存数据,能非常轻松的实现缓存过期刷新机制. 多种语言都可以连接到 ...

  9. Docker中进入容器命令行及后台运行

    Docker中我们一般会有两种执行命令的方式,一种是直接进入容器的命令行,在终端执行并查看结果,一种是在后台执行,并不会在终端查看结果. 1.进入容器命令行 su root docker run -i ...

  10. NCCL(Nvidia Collective multi-GPU Communication Library) Nvidia英伟达的Multi-GPU多卡通信框架NCCL 学习;PCIe 速率调研;

    为了了解,上来先看几篇中文博客进行简单了解: 如何理解Nvidia英伟达的Multi-GPU多卡通信框架NCCL?(较为优秀的文章) 使用NCCL进行NVIDIA GPU卡之间的通信(GPU卡通信模式 ...