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= ...
随机推荐
- Ajax跨域请求怎么解决?
前言 项目中需要将第三方系统中,对应用户的代办消息集成到系统中.对方提供了获取对应用户的接口url,但是由于两边的系统是部署到客户现场不同IP的虚机上的,所以进行ajax请求的时候是属于跨域请求的.之 ...
- Python之数据处理
一.CSV数据处理 CSV文件格式:逗号分隔值(Comma-Separated Value,CSV,有时也称为字符分隔值,因为分隔符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本).纯文 ...
- springboot jpa操作redis
SpringBoot使用Redis缓存 (1)pom.xml引入jar包,如下: <dependency> <groupId>org.springframework.boo ...
- libevent学习一
常见的异步IO存在的问题: 1.使用 fcntl(fd, F_SETFL, O_NONBLOCK);,为什么在处理上效率不好. a.在没有数据可读写的时候,循环会不停执行,浪费掉大部分 ...
- 「日常训练」All Friends(POJ-2989)
题意 分析 代码 #include <iostream> #include <cstring> #include <algorithm> #define MP ma ...
- 用最简单的MVC模式输出内容
MVC是模型(model)-视图(view)-控制器(controller)的缩写,它的作用是使代码分离,可维护性高.重用性高 编写Model层: <?php class model{ publ ...
- Python学习-猜数字游戏
菩萨蛮·黄鹤楼 茫茫九派流中国,沉沉一线穿南北.烟雨莽苍苍,龟蛇锁大江. 黄鹤知何去,剩有游人处.把酒酹滔滔,心潮逐浪高! --coding:UTF-8-- import random secret ...
- CodeForces 838B Diverging Directions 兼【20180808模拟测试】t3
描述 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点到达. 2. 接下来的 N-1 ...
- JDK源码分析:Short.java
Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short ...
- Linux的基础预备知识
Linux下一切皆文件 1.root@mk-virtual-machine:/home/mk# root:该位置表示当前终端登录的用户名 mk-virtual-machine:/home/m ...