BZOJ4823 CQOI2017老C的方块(最小割)
如果将其转化为一个更一般的问题即二分图带权最小单边点覆盖(最小控制集)感觉是非常npc的。考虑原题给的一大堆东西究竟有什么奇怪的性质。
容易发现如果与特殊边相邻的两格子都放了方块,并且这两个格子都各有另一个相邻格子放了方块,其组成的连通块就是需要破坏的。自然四个格子都可以选择破坏。可以发现如果在中间的两个格子里选的话,应该选择破坏权值较小的,因为其对其他格子没有影响。同时注意到另两个格子在黑白染色的图中一定是不同色的。
那么做法就很显然了,建四层点,外部两层是不与特殊边相邻的黑白点,内部两层是与特殊边相邻的黑白点,外部点分别与源汇连边权为其权值的边,内部点之间连边权为较小权值的边,外部点和内部点之间连inf边,跑最小割即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
#define N 100010
#define S 0
#define T 100001
#define inf 1000000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int c,r,n,p[N],t=-;
int d[N],cur[N],q[N],ans;
struct data{int to,nxt,cap,flow;
}edge[N<<];
struct data2{int x,y;
}a[N];
map<int,int> f[N],id[N];
int wx[]={,,,-},wy[]={,,-,};
void addedge(int x,int y,int z)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
}
bool isblack(int x,int y){return x+y&;}
bool isnear(int x,int y){return x&?y%==||y%==:y%==||y%==;}
bool bfs()
{
memset(d,,sizeof(d));d[S]=;
int head=,tail=;q[]=S;
do
{
int x=q[++head];
for (int i=p[x];~i;i=edge[i].nxt)
if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
{
d[edge[i].to]=d[x]+;
q[++tail]=edge[i].to;
}
}while (head<tail);
return ~d[T];
}
int work(int k,int f)
{
if (k==T) return f;
int used=;
for (int i=cur[k];~i;i=edge[i].nxt)
if (d[k]+==d[edge[i].to])
{
int w=work(edge[i].to,min(f-used,edge[i].cap-edge[i].flow));
edge[i].flow+=w,edge[i^].flow-=w;
if (edge[i].flow<edge[i].cap) cur[k]=i;
used+=w;if (used==f) return f;
}
if (used==) d[k]=-;
return used;
}
void dinic()
{
while (bfs())
{
memcpy(cur,p,sizeof(p));
ans+=work(S,inf);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4823.in","r",stdin);
freopen("bzoj4823.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
c=read(),r=read(),n=read();
memset(p,,sizeof(p));
for (int i=;i<=n;i++)
{
int y=read(),x=read(),z=read();
f[a[i].x=x][a[i].y=y]=z;id[x][y]=i;
}
for (int i=;i<=n;i++)
if (!isnear(a[i].x,a[i].y)&&isblack(a[i].x,a[i].y))
{
addedge(S,i,f[a[i].x][a[i].y]);
for (int j=;j<;j++)
if (isnear(a[i].x+wx[j],a[i].y+wy[j])&&id[a[i].x+wx[j]][a[i].y+wy[j]])
for (int k=;k<;k++)
if (isnear(a[i].x+wx[j]+wx[k],a[i].y+wy[j]+wy[k])&&id[a[i].x+wx[j]+wx[k]][a[i].y+wy[j]+wy[k]])
for (int x=;x<;x++)
{
int u=a[i].x+wx[j]+wx[k]+wx[x],v=a[i].y+wy[j]+wy[k]+wy[x];
if (!isnear(u,v)&&id[u][v]) addedge(i,id[a[i].x+wx[j]][a[i].y+wy[j]],inf),addedge(id[a[i].x+wx[j]+wx[k]][a[i].y+wy[j]+wy[k]],id[u][v],inf);
}
}
for (int i=;i<=n;i++)
if (!isnear(a[i].x,a[i].y)&&!isblack(a[i].x,a[i].y)) addedge(i,T,f[a[i].x][a[i].y]);
for (int i=;i<=n;i++)
if (isnear(a[i].x,a[i].y)&&!isblack(a[i].x,a[i].y))
for (int j=;j<;j++)
if (isnear(a[i].x+wx[j],a[i].y+wy[j])&&id[a[i].x+wx[j]][a[i].y+wy[j]])
addedge(i,id[a[i].x+wx[j]][a[i].y+wy[j]],min(f[a[i].x][a[i].y],f[a[i].x+wx[j]][a[i].y+wy[j]]));
dinic();
cout<<ans;
return ;
}
BZOJ4823 CQOI2017老C的方块(最小割)的更多相关文章
- bzoj4823: [Cqoi2017]老C的方块(最小割)
4823: [Cqoi2017]老C的方块 题目:传送门 题解: 毒瘤题ORZ.... 太菜了看出来是最小割啥边都不会建...狂%大佬强强强 黑白染色?不!是四个色一起染,四层图跑最小割... 很 ...
- bzoj 4823: [Cqoi2017]老C的方块 [最小割]
4823: [Cqoi2017]老C的方块 题意: 鬼畜方块游戏不解释... 有些特殊边,有些四个方块组成的图形,方块有代价,删掉一些方块使得没有图形,最小化代价. 比较明显的最小割,一个图形中必须删 ...
- 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 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
- 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 题解 首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑. 为了和其他格子区分,我们把两侧的这两个格子 ...
- 【洛谷P3756】[CQOI2017]老C的方块(最小割)
洛谷 题意: 给出一个网格图类似于这样: 现在给出一个\(n*m\)大小的网格,之后会给出一些点,若某些点相连形成了如下的几个图案,那么就是不好的. 现在可以删去一些点,但删除每个点都有一些代价,问最 ...
- BZOJ 4823 Luogu P3756 [CQOI2017]老C的方块 (网络流、最小割)
题目链接 (Luogu) https://www.luogu.org/problem/P3756 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id= ...
随机推荐
- Android APP架构设计——MVC、MVP和MVVM介绍
)对于过大的项目,数据绑定需要花费更多的内存. 关于APP的架构设计就介绍到这吧,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/529 ...
- Java集合——ArrayList源码详解
) ArrayList 实现了RandomAccess, Cloneable, java.io.Serializable三个标记接口,表示它自身支持快速随机访问,克隆,序列化. public clas ...
- EL/JSTL-jsp页面更简单的输出方式
1.EL(Expression Language):表达式语言,用于页面输出 格式:${表达式} EL支持四则运算,关系运算[常用eq来比较字符串或判断相等],逻辑运算 EL访问空间内对象,[类.对象 ...
- 北京Uber优步司机奖励政策(3月9日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- orm4sqlite
//-------------------------------------------------------------------------- // // Copyright (c) BUS ...
- DSP5509的GPIO学习-第5篇
1. 使用CCS V6.1版本,目前已经不局限于仅仅把实验搞清楚了,要深入去探究内部的原理,本章看下GPIO实验 2. 在CCS启动的时候,提示,这个问题是什么,XDAIS是什么?XDAIS (eXp ...
- vim 安装
Ubuntu 16.04 下 Vim安装及配置 默认已经安装了VIM-tiny linuxidc@linuxidc:~$ locate vi | grep 'vi$' |xargs ls -al lr ...
- xencenter迁移云主机方法
问题:POOL中计算节点内存不足. 解决方法:1.为计算节点添加内存(费用高)2.将部分资源迁移到其它POOL中. 方法: 1.选择要迁移的虚拟机 2.选择保存路径 这里可以看到可以批量导出: 注意: ...
- vue2组件之间双向数据绑定问题
最近在使用element-ui的dialog组件二次封装成独立组件使用时,子组件需要将关闭dialog状态返回给父组件,简单的说就是要实现父子组件之间的数据双向绑定问题. 大致代码如下: 1,父组件 ...
- 使用Python访问HDFS
最近接触到大数据,对于Skpark和Hadoop的料及都停留在第一次听到这个名词时去搜一把看看大概介绍免得跟不上时代的层次. 在实际读了点别人的代码,又自己写了一些之后,虽然谈不上理解加深,至少对于大 ...