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

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

  2. 成都Uber优步司机奖励政策(8月31日~9月6日)

    本周(8月31日-9月6日),优步成都继续推出丰厚保底奖励,日保底总金额最高575元,每周保底最高可获得3595元.优步还加大了乘客端折扣力度,最低五折坐车!单子超多,上线就有单,接单接不停!欢迎各位 ...

  3. CF 314 E. Sereja and Squares

    E. Sereja and Squares http://codeforces.com/contest/314/problem/E 题意: 给你一个擦去了部分左括号和全部右括号的括号序列,括号有25种 ...

  4. LeetCode:34. Search for a Range(Medium)

    1. 原题链接 https://leetcode.com/problems/search-for-a-range/description/ 2. 题目要求 给定一个按升序排列的整型数组nums[ ]和 ...

  5. ubuntu网卡

    查看网卡类型  http://blog.csdn.net/eddy_liu/article/details/6578819 qii@ubuntu:~$ lspci | grep -i net 03:0 ...

  6. 10、Java并发编程:并发容器之ConcurrentHashMap

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  7. c的多态

    使用函数数组,实现多态 参考my_strtoll10

  8. 微信小程序—day02

    全局配置 在app.json中,对小程序进行全局配置.官方文档 tabBar是对底部/顶部导航栏的配置,图片的icon 大小限制为40kb,建议尺寸为 81px * 81px 去阿里矢量图网站,找到图 ...

  9. 【CentOS】下安装RabbitMQ教程

    系统版本: 安装依赖: 由于RabbitMQ依赖Erlang, 所以需要先安装Erlang. Erlang的安装方式大概有两种: (1) Erlang Solution安装(推荐) wget http ...

  10. HDU - 6444(单调队列+思维)

    链接:HDU - 6444 题意:给出一个包含 n 个数的环,每个数都有一个价值,起点任选,每次跳顺时针跳 k 个数,在哪个数就能获得该价值(包括起点),最多取 m 次,问最少需要补充多少价值,所拿的 ...