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

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

  2. 北京Uber优步司机奖励政策(12月15日)

    用户组:人民优步及电动车(适用于12月15日) 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:htt ...

  3. linux 学习总结---- mysql 总结

    用户的创建 ---->修改 ---->删除用户 create alter drop (数据定义语言 DDL) 授权: insert update delete grant *.* revo ...

  4. JS原型链与继承别再被问倒了

    原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实 ...

  5. [python]np.loadtxt报错

    np.loadtxt报错 通过pandas生成的cvs数据利用nump.loadtxt读取的时候 tmp = np.loadtxt('test.csv', dtype=np.str, delimite ...

  6. 服务器返回中文乱码的情况(UTF8编码 -> 转化为 SYSTEM_LOCALE 编码)

    服务器乱码 转换使用如下方法 入惨{“msg”} -> utf8编码 -> 转化为 SYSTEM_LOCALE 编码 -> 接受转换后的参数 "sEncoding" ...

  7. Java学习笔记-序

    最近开始学习java了,上班看书看得经常瞌睡,有时候想起来觉得挺重要的知识点想记在哪里又害怕忘记了,于是乎突然想到了博客园,所以今天上午就决定记在院子里了,先写了8是因为已经看到第八章了(读的是Jav ...

  8. Python3 Tkinter-Spinbox

    1.创建 from tkinter import * root=Tk() Spinbox(root).pack() root.mainloop() 2.参数 from_    最小值 to    最大 ...

  9. css模仿微信弹出菜单

      css模仿微信弹出菜单 效果图: html: <div class="action-sheet-backdrop"> <div class="act ...

  10. 4-1:实现tee命令

    #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h& ...