如果将其转化为一个更一般的问题即二分图带权最小单边点覆盖(最小控制集)感觉是非常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的方块(最小割)的更多相关文章

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

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

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

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

  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. bzoj 4823 & 洛谷 P3756 老C的方块 —— 最小割

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823 https://www.luogu.org/problemnew/show/P3756 ...

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

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

  8. 【洛谷P3756】[CQOI2017]老C的方块(最小割)

    洛谷 题意: 给出一个网格图类似于这样: 现在给出一个\(n*m\)大小的网格,之后会给出一些点,若某些点相连形成了如下的几个图案,那么就是不好的. 现在可以删去一些点,但删除每个点都有一些代价,问最 ...

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

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

随机推荐

  1. 北京Uber优步司机奖励政策(1月18日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. 微信小程序学习笔记(1)- 按钮触发的函数的定义以及不同页面之间的数据传递

    <view class='item' bindtap='onCountryTab' data-idx='4'> 1)bindtap属性用来设置控件需要绑定的函数,函数用单引号括起来:. 2 ...

  3. 如何在Mac OS系统下搭建Java开发环境 配置Java环境变量

    1. 打开终端   在finder里面搜索(这台MAC)查找终端   2. 在cdlouiedeAir:~ cdlouie$(cdlouie是我的电脑用户名) 后面输入sudo vim /etc/pr ...

  4. 「日常训练」Card Game Cheater(HDU-1528)

    题意与分析 题意是这样的:有\(n\)张牌,然后第一行是Adam的牌,第二行是Eve的牌:每两个字符代表一张牌,第一个字符表示牌的点数,第二个表示牌的花色.Adam和Eve每次从自己的牌中选出一张牌进 ...

  5. svn清理报错:Cleanup failed to process the following paths

    这里碰到svn更新时,提示清理,清理时报错: 只需进行以下几个步骤即可解决:(原理即是清除掉svn数据库里的lock记录) 1.下载SQLiteManager,svn用的是sqlite数据库,需要一款 ...

  6. 爬虫2.1-scrapy框架-两种爬虫对比

    目录 scrapy框架-两种爬虫对比和大概流程 1. 传统spider爬虫 2. crawl型爬虫 3. 循环页面请求 4. scrapy框架爬虫的大致流程 scrapy框架-两种爬虫对比和大概流程 ...

  7. 在使用Pipeline串联多个stage时model和非model的区别

    train.csv数据: id,name,age,sex1,lyy,20,F2,rdd,20,M3,nyc,18,M4,mzy,10,M 数据读取: SparkSession spark = Spar ...

  8. ionic 组件学习

    利用css列表多选框: <div class="{{Conceal}}" > <ion-checkbox color="secondary" ...

  9. Dask教程

    Dask 介绍 Dask是一款用于分析计算的灵活并行计算库. Dask由两部分组成: 针对计算优化的动态任务调度.这与Airflow,Luigi,Celery或Make类似,但针对交互式计算工作负载进 ...

  10. python计算工资个税

    # -*- coding: utf-8 -*- total = int(input("税前总计:")) #公积金10% Gongjijin = total * 0.1 print( ...