BZOJ4625 [BJOI2016]水晶 最小割
题意简述
给你一个三维的坐标系,坐标系上 \((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]水晶 最小割的更多相关文章
- 【BZOJ-1976】能量魔方Cube 最小割 + 黑白染色
1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 884 Solved: 307[Submi ...
- Bzoj 1976: [BeiJing2010组队]能量魔方 Cube 最小割,最大流
1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 879 Solved: 304[Submi ...
- [bzoj4625][BeiJing2016]水晶
来自FallDream的博客,未经允许,请勿转载,谢谢. 不用惊慌,今天的题都不是小强出的.——融入了无数心血的作品,现在却不得不亲手毁掉,难以体会他的心情啊 .——那也是没有办法的事情,能量共振不消 ...
- 【BZOJ1976】能量魔方 [最小割]
能量魔方 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description 小C 有一个能量魔方,这个魔方可神奇 ...
- 【BZOJ1976】[BeiJing2010组队]能量魔方 Cube 最小割
[BZOJ1976][BeiJing2010组队]能量魔方 Cube Description 小C 有一个能量魔方,这个魔方可神奇了,只要按照特定方式,放入不同的 能量水晶,就可以产生巨大的能量. 能 ...
- 【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割
题目描述 一个n*n*n的立方体,每个位置为0或1.有些位置已经确定,还有一些需要待填入.问最后可以得到的 相邻且填入的数不同的点对 的数目最大. 输入 第一行包含一个数N,表示魔方的大小. 接下来 ...
- BZOJ 1391: [Ceoi2008]order [最小割]
1391: [Ceoi2008]order Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1509 Solved: 460[Submit][Statu ...
- BZOJ-2127-happiness(最小割)
2127: happiness(题解) Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1806 Solved: 875 Description 高一 ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
随机推荐
- 以非root身份安装Python的Module或者Package以及pip安装指定路径
因为要远程访问公司的服务器,没有sudo的权限,所以在安装python的一些包的时候就不能安去默认路径了(比如以/usr/local/lib/为prefix的路径). 一般来讲用easy_instal ...
- IDE引入mindmap插件,在项目中添加思维导图
1.打开IDE,file--settings--plugins,搜索IDEA Mind Map 2.点击install,进行下载,然后按照提示restart重启IDEA,安装完成 3.创建mind m ...
- spring(二) AOP注入
AOP概念 l AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码 l 经典应用:事务管理.性能监视.安全检查.缓存 .日志等 l Spring AOP使用纯Java实现,不需要专门的编译 ...
- IP子网的划分
一.划分子网的具体步骤 已知192.168.1.0/24,划分8个子网(一个ip划分8个子网,即网络位不再是24位)1100 0000.1010 1000.0000 0001.0000 00001 . ...
- CNN文本分类
CNN用于文本分类本就是一个不完美的解决方案,因为CNN要求输入都是一定长度的,而对于文本分类问题,文本序列是不定长的,RNN可以完美解决序列不定长问题, 因为RNN不要求输入是一定长度的.那么对于C ...
- python每日一练:0011题
第 0011 题: 敏感词文本文件 filtered_words.txt,里面的内容为以下内容,当用户输入敏感词语时,则打印出 Freedom,否则打印出 Human Rights. 北京 程序员 公 ...
- [2019徐州网络赛J题]Random Access Iterator
题目链接 大致题意:从根节点出发,在节点x有son[x]次等概率进入儿子节点,求到达最深深度的概率.son[x]为x节点的儿子节点个数. 又又又又没做出来,心态崩了. 下来看了官方题解后发觉自己大体思 ...
- qt 获取磁盘空间大小,cpu利用率,内存使用率
转自:http://www.qtcn.org/bbs/read-htm-tid-60613.html. 1:封装成一个类,直接调用即可.已经在多个商业项目中使用.2:所有功能全平台 win linux ...
- idea 代码部分格式化
效果: 处理Idea使用ctrl+alt+L进行代码格式化时部分代码可以被忽略,不执行格式化功能(webstorm,phpstorm同理) 原因: 有时希望自己写的一些代码不被格式化,或者发现格式化后 ...
- ftok用法
转载: http://www.cnblogs.com/hjslovewcl/archive/2011/03/03/2314344.html http://www.cnblogs.com/lihaozy ...