题意简述

给你一个三维的坐标系,坐标系上 \((x_i+y_i+z_i)\bmod 3 = 0\) 的点内有能量源。给定 \(n\) 个点含有能量值为 \(c_i\) 的水晶,如果一个水晶位于能量源上,这个水晶的能量值将会提高 \(10\%\)。

水晶有两种共振情况,一是相邻的三个水晶共振,二是两个水晶在一条长度为 \(2\) 的线段两端,且线段中点是能量源。

你可以炸掉一些水晶,请问没有共振之后剩余水晶的最大能量值。

做法

对于 \((x_i+y_i+z_i)\bmod 3 \not = 0\) 的点黑白染色,如果一个能量源的周围同时存在黑白两种颜色的点,那么必定构成共振,如图所示

于是我们可以把 \(\bmod 3\) 意义下的三种点分别拆点。考虑对于每个共振,要用最小代价破坏,显然是一个最小割的模型。把每个点拆点,边权为水晶的能量值 \(c_i\) 。然后源点连 \(1\) 的点,\(1\) 连 \(0\),\(0\) 连 \(2\),\(2\) 连 汇点,答案为水晶的总能量 \(\sum c_i\) 减最大流。这里给出代码实现:

const int inf=1e9;
inline void link(int a,int b,int c)
{
add_edge(S,a<<1,inf);add_edge(a<<1|1,b<<1,inf);
add_edge(b<<1|1,c<<1,inf);add_edge(c<<1|1,T,inf);
}

然后我们用一个结构体来表示每一个点,将\((x_i,y_i,z_i)\)转换为\((x_i-z_i,y_i-z_i)\),用一个向量的结构体来封存,重载<+预算符,用一个map来对向量进行操作,本题就结束了。

代码实现

map常数大跑不快,但是很好写。

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
#define ak *
#define in inline
#define db double
in char getch()
{
static char buf[1<<12],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<12,stdin),p1==p2)?EOF:*p1++;
}
char qwq;
#define gc() getchar()
in int read()
{
re cz=0,ioi=1;qwq=gc();
while(qwq<'0'||qwq>'9') ioi=qwq=='-'?~ioi+1:1,qwq=gc();
while(qwq>='0'&&qwq<='9') cz=(cz<<3)+(cz<<1)+(qwq^48),qwq=gc();
return cz ak ioi;
}
const int N=5e4+5,inf=1e9;
int n,m,h[N<<1],cnt=1,dis[N<<1],s,t,q[N<<1],l,r,cur[N<<1],tot,sum;
struct did{int next,to,f;}e[N*20];
in void add(re x,re y,re z)
{
e[++cnt]=(did){h[x],y,z},h[x]=cnt;
e[++cnt]=(did){h[y],x,0},h[y]=cnt;
}
const db eps=1e-9;
inline int bfs(re u)
{
memset(dis,-1,sizeof(dis));dis[u]=0;
l=r=0;q[++r]=u;
while(l<r)
{
re i=q[++l]; if(i==t) return 1;
for(re j=h[i],k;k=e[j].to,j;j=e[j].next)
if(dis[k]<0&&e[j].f) dis[k]=dis[i]+1,q[++r]=k;
}
return 0;
}
in int dfs(re u,re maxf)
{
re res=0;
if(u==t||!maxf) return maxf;
for(re &i=cur[u],v;v=e[i].to,i;i=e[i].next)
if(e[i].f&&dis[v]==dis[u]+1)
{
re delta=dfs(v,min(maxf,e[i].f));
e[i].f-=delta;e[i^1].f+=delta;
res+=delta;maxf-=delta;
if(!maxf) return res;
}
if (fabs(maxf-res)<eps) dis[u]=-2;
return res;
}
inline int dinic()
{
re ans=0;
while(bfs(s)) memcpy(cur,h,sizeof(h)),ans+=dfs(s,inf);
return ans;
}
struct poi //poipoi qwq~
{
int x,y;
poi (re a=0,re b=0) {x=a,y=b;}
in bool operator < (poi a) const {return x==a.x?y<a.y:x<a.x;}
in poi operator + (poi a) const {return poi(x+a.x,y+a.y);}
}p[N];
map<poi,int>mp,ext,f,book;
in void link(re a,re b,re c)
{
if(!book[poi(s,a)]) add(s,a<<1,inf),book[poi(1,a)]=1;
if(!book[poi(a,b)]) add(a<<1|1,b<<1,inf),book[poi(a,b)]=1;
if(!book[poi(b,c)]) add(b<<1|1,c<<1,inf),book[poi(b,c)]=1;
if(!book[poi(c,t)]) add(c<<1|1,t,inf),book[poi(c,a)]=1;
}
int main()
{
n=read();
for(re i=1;i<=n;i++)
{
re x=read(),y=read(),z=read(),c=read();
p[i]=poi(x-z,y-z);if(!ext[p[i]]) ext[p[i]]=++tot;
mp[p[i]]+=c;f[p[i]]=((x+y+z)%3==0);
}
s=1,t=tot+1<<1;
for(re i=1;i<=n;i++) if(f[p[i]]<2)
{
re pt=ext[p[i]],ene=mp[p[i]]*(10+f[p[i]]);sum+=ene;
add(2*pt,2*pt+1,ene);if(!f[p[i]]) {f[p[i]]=2;continue;}
static int a[N],b[N];re na=0,nb=0;f[p[i]]=2;
if(!(a[++na]=ext[p[i]+poi(0,1)])) na--;
if(!(a[++na]=ext[p[i]+poi(1,0)])) na--;
if(!(a[++na]=ext[p[i]+poi(-1,-1)])) na--;
if(!(b[++nb]=ext[p[i]+poi(0,-1)])) nb--;
if(!(b[++nb]=ext[p[i]+poi(-1,0)])) nb--;
if(!(b[++nb]=ext[p[i]+poi(1,1)])) nb--;
for(re x=1;x<=na;x++)
for(re y=1;y<=nb;y++)
link(a[x],pt,b[y]);
}
printf("%.1lf",(db)(sum-dinic())/10);
return 0;
}

BZOJ4625 [BJOI2016]水晶 最小割的更多相关文章

  1. 【BZOJ-1976】能量魔方Cube 最小割 + 黑白染色

    1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 884  Solved: 307[Submi ...

  2. Bzoj 1976: [BeiJing2010组队]能量魔方 Cube 最小割,最大流

    1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 879  Solved: 304[Submi ...

  3. [bzoj4625][BeiJing2016]水晶

    来自FallDream的博客,未经允许,请勿转载,谢谢. 不用惊慌,今天的题都不是小强出的.——融入了无数心血的作品,现在却不得不亲手毁掉,难以体会他的心情啊 .——那也是没有办法的事情,能量共振不消 ...

  4. 【BZOJ1976】能量魔方 [最小割]

    能量魔方 Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description 小C 有一个能量魔方,这个魔方可神奇 ...

  5. 【BZOJ1976】[BeiJing2010组队]能量魔方 Cube 最小割

    [BZOJ1976][BeiJing2010组队]能量魔方 Cube Description 小C 有一个能量魔方,这个魔方可神奇了,只要按照特定方式,放入不同的 能量水晶,就可以产生巨大的能量. 能 ...

  6. 【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割

    题目描述 一个n*n*n的立方体,每个位置为0或1.有些位置已经确定,还有一些需要待填入.问最后可以得到的 相邻且填入的数不同的点对 的数目最大. 输入 第一行包含一个数N,表示魔方的大小. 接下来 ...

  7. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

  8. BZOJ-2127-happiness(最小割)

    2127: happiness(题解) Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1806  Solved: 875 Description 高一 ...

  9. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

随机推荐

  1. 自动化运维--ansible(2)

    问题一:如何在多台服务器中配置Web项目上线的所有环境 解答: 1.使用ansible配置nginx服务 在安装前了解rpm与yum的区别  rpm是压缩包安装依赖包需要自己手动安装,yum安装解决依 ...

  2. Python 笔试集(4):True + True == ?

    目录 目录 前文列表 面试题True Ture 布尔值 布尔类型是特殊的整数类型 前文列表 Python 笔试集:什么时候 i = i + 1 并不等于 i += 1? Python 笔试集(1):关 ...

  3. C# 程序异常停止后,sqlite可能变成0kb……

    解决办法就是即时备份数据库文件,启动时判断数据库文件是否为0kb,是则还原之

  4. Lesson 4 The double life of Alfred Bloggs

    There are two type of people in the society. People who do manual works can higher payment than peop ...

  5. 精读《Optional chaining》

    1. 引言 备受开发者喜爱的特性 Optional chaining 在 2019.6.5 进入了 stage2,让我们详细读一下草案,了解一下这个特性的用法以及讨论要点. 借着这次精读草案,让我们了 ...

  6. [CF585E]Marbles

    Description: 给定一个序列 \(a_i\) ,每次可以交换相邻两个元素,求使序列变成若干个极大连续段,每个极大连续段内部的值相同且任意两个极大连续段的值互不相同. \(n\le 4\tim ...

  7. Spring aop 实例(转)

    面向切面编程,有效的降低了代码之间的耦合性,易于维护:例如:我们习惯在代码中加上一些日志信息,在程序出错时方便快速查找找到问题,通常做法是在请求进入方法的时候打印日志,退出前打印日志,还有在出错时打印 ...

  8. Vue 中如何定义全局的变量和常量

    Vue 中如何定义全局的变量和常量 我想要定义一个变量, 在项目的任何地方都可以访问到, 不需要每一次使用的时候, 都引入. 尝试1:创建 global.js 并且在其中定义   let a = 10 ...

  9. 吴恩达深度学习:2.1Logistic Regression逻辑回归及其损失函数

    1.Logistic Regression是一个二元分类问题 (1)已知输入的特征向量x可能是一张图,你希望把它识别出来,这是不是猫图,你需要一个算法,可以给出预测值,更正式的y是一个概率,当输入特征 ...

  10. author认证模块

    author认证模块 用auth模块 你就用全套 不是自己写一部分 用别人一部分 ​ 创建超级管理员,用于登录DJango admin的后台管理 ​ 命令:createsuperuser,输入顺序用户 ...