[BJOI2016]水晶 做题心得

这是一个写了我两小时的傻逼题。写这个题浪费了一堆时间后,我才意识到我码力又不行了。于是整理起了实现技巧,开始练码力。

思路

不难。首先把 \((x,y,z)\) 变成 \((x-z,y-z)\)。因为发现 \((x,y,z)\) 同时减去某个数表示的位置不变,同时减去 \(z\),把坐标只用 \(x,y\) 来描述。

发现是关于点权的,先把每个点拆成入点和出点,连一条边表示它的点权。假设入,出点分别是 \(a_i,a_o\)

然后枚举一下每个三角形,每个直线,假设是 \((a,b,c)\)。

那么这样连边:

\(S \xrightarrow[INF]{} a_i \xrightarrow[val_a]{} a_o \xrightarrow[INF]{} b_i\xrightarrow[val_b]{} b_o\xrightarrow[INF]{} c_i\xrightarrow[val_c]{}c_o\xrightarrow[INF]{} T\)

实现问题&改进

  1. 发现这样连边会连出环来。解法是,考虑按 \((x+y)\%3\) 分类,强行钦定某个顺序。这样就不会产生环了。

  2. 分开考虑三角形和直线太麻烦了,而且非常容易写错。我因此写错了 \(114514\) 次。事实上可以一块考虑,对于每个\((x+y)\%3=0\) 的,考虑它的“六周” (“四周”这个词在本题中的引申,注意到相邻的有六个点),不能有相邻的 \(\%3=1\) 和 \(\%3=2\) 的。

    然后可以这样建,\(\%3=1\) 的接 \(S\),\(\%3=2\) 的接 \(T\),\(\%3=0\) 的,向周围的 \(\%3=2\) 的连一条,然后周围 \(\%3=1\) 的向它来连一条,就可以完成建图了

    这样结构更加清楚,简单,不容易写挂

    (是参考了一篇题解中的实现

代码

#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 400005
#define INF 600000000
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define Tra(i,u) for(int i=G.st(u),v=G.to(i);~i;i=G.nx(i),v=G.to(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define all(a) a.begin(),a.end()
#define iter(a,p) (a.begin()+p)
int I() {char c=getchar(); int x=0; int f=1; while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return ((f==1)?x:-x);}
template <typename T> void Rd(T& arg){arg=I();}
template <typename T,typename...Types> void Rd(T& arg,Types&...args){arg=I(); Rd(args...);}
void RA(int *p,int n) {F(i,1,n) *p=I(),++p;}
int n;
int x[N],y[N],c[N];
map<pair<int,int>,int> rec,rid;
#define rc(x,y) rec[make_pair(x,y)]
#define ri(x,y) rid[make_pair(x,y)]
void Input()
{
n=I();
F(i,1,n)
{
int z; Rd(x[i],y[i],z,c[i]); c[i]*=10;
x[i]-=z; y[i]-=z;
if ((x[i]+y[i])%3==0) c[i]+=c[i]/10; rc(x[i],y[i])+=c[i];
}
}
class NetworkFlow
{
public:
int S,T,n;
struct edge
{
int v,c,nx;
}pool_e[4000000+2]; edge *e;
int pool_h[N+2]; int *head;
int pool_c[N+2]; int *cur;
int ecnt=-1;
void clear()
{
ecnt=-1;
MEM(pool_e,-1); e=pool_e+2;
MEM(pool_h,-1); head=pool_h+2;
MEM(pool_c,-1); cur=pool_c+2;
// 允许 [-1]的访问
}
void add(int u,int v,int c)
{
e[++ecnt]={v,c,head[u]}; head[u]=ecnt;
}
void addflow(int u,int v,int c)
{
// printf("flow %d %d %d\n",u,v,c);
add(u,v,c);
add(v,u,0);
}
int& st(int u) {return head[u];}
int& cu(int u) {return cur[u];}
int& to(int i) {return e[i].v;}
int& cap(int i) {return e[i].c;}
int& nx(int i) {return e[i].nx;}
#define Trah(i,u) for(int i=st(u),v=to(i);~i;i=nx(i),v=to(i))
#define Trac(i,u) for(int &i=cu(u),v=to(i);~i;i=nx(i),v=to(i)) queue<int> Q;
int dep[N];
bool BFS()
{
while(!Q.empty()) Q.pop(); F(i,1,n) dep[i]=INF;
dep[S]=1; cur[S]=head[S]; Q.push(S);
while(!Q.empty())
{
int u=Q.front(); Q.pop();
if (u==T) return true;
Trah(i,u) if (cap(i) and dep[v]==INF)
{
dep[v]=dep[u]+1;
cur[v]=head[v];
Q.push(v);
}
}
return false;
}
int DFS(int u,int flow)
{
if (u==T) return flow;
int ans=0;
Trac(i,u)
{
if (!flow) break;
if (cap(i) and dep[v]==dep[u]+1)
{
int f=DFS(v,min(flow,cap(i)));
if (!f)
{
dep[v]=INF;
}
else
{
cap(i)-=f; cap(i^1)+=f;
flow-=f; ans+=f;
}
}
}
return ans;
}
int Dinic()
{
int ans=0;
while(BFS()) ans+=DFS(S,INF);
return ans;
} NetworkFlow() {clear();}
NetworkFlow(int s,int t,int nn) {clear(); S=s; T=t; n=nn;}
}Nt;
int tot=0,S=1,T=2;
int in[N],out[N];
void Sakuya()
{
int point=0;
tot=2;
F(i,1,n) c[i]=x[i]=y[i]=0;
for(auto p:rec)
{
int i=p.first.first,j=p.first.second;
++point; x[point]=i;
y[point]=j;
c[point]=rc(i,j);
ri(i,j)=point;
in[point]=++tot;
out[point]=++tot;
}
Nt=NetworkFlow(S,T,tot);
F(i,1,point)
{
int t=((x[i]+y[i])%3+3)%3;
if (t==1) Nt.addflow(S,in[i],INF);
if (t==2) Nt.addflow(out[i],T,INF);
else
{
int nx;
nx=ri(x[i]-1,y[i]-1); if (nx) Nt.addflow(out[nx],in[i],INF);
nx=ri(x[i]+1,y[i]); if (nx) Nt.addflow(out[nx],in[i],INF);
nx=ri(x[i],y[i]+1); if (nx) Nt.addflow(out[nx],in[i],INF); nx=ri(x[i]+1,y[i]+1); if (nx) Nt.addflow(out[i],in[nx],INF);
nx=ri(x[i]-1,y[i]); if (nx) Nt.addflow(out[i],in[nx],INF);
nx=ri(x[i],y[i]-1); if (nx) Nt.addflow(out[i],in[nx],INF);
}
Nt.addflow(in[i],out[i],c[i]);
} int sum=0; F(i,1,point) sum+=c[i];
int ans=sum-Nt.Dinic();
printf("%d.%d\n",ans/10,ans%10);
}
void IsMyWife()
{
Input();
Sakuya();
}
}
#undef int //long long
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();
return 0;
}

后记:两种实现的比较

  1. 原实现长达 \(220\) 行,改进实现只有 \(182\) 行。

  2. 原实现(提到过)WA了 \(114514\) 次,最高拿了 \(35\),到现在还不知道问题在哪,没调出来,也不想调了,nmsl (暴躁)

    相比较改进实现一遍就A了。

所以说,码力的提升还是很重要的。

[BJOI2016]水晶 做题心得的更多相关文章

  1. [JSOI2019]节日庆典 做题心得

    [JSOI2019]节日庆典 做题心得 一个性质有趣的字符串题 这要是在考场上我肯定做不出来吧 一开始还以为要 SAM 什么的暴力搞,没想到只用到了 \(Z\) 函数 -- 也是我生疏了罢 (学了啥忘 ...

  2. CF1416D 做题心得

    CF1416D 做题心得 上次在某trick中提到了这个题,一开始觉得太毒瘤没有写,现在把它补上了. 感觉实现这个东西,比单纯收获一个trick,收获的东西多太多了. 主要思路 它的主要trick是& ...

  3. [NOIP补坑计划]NOIP2017 题解&做题心得

    终于做完了…… 场上预计得分:?(省一分数线:295) 由于看过部分题解所以没有预计得分qwq 题解: D1T1 小凯的疑惑 题面 震惊!一道小学奥数题竟难倒无数高中考生! 欢迎大家以各种姿势*和谐* ...

  4. [NOIP补坑计划]NOIP2016 题解&做题心得

    感觉16年好难啊QAQ,两天的T2T3是不是都放反了啊…… 场上预计得分:100+80+100+100+65+100=545(省一分数线280) ps:loj没有部分分,部分分见洛咕 题解: D1T1 ...

  5. [NOIP补坑计划]NOIP2015 题解&做题心得

    感觉从15年开始noip就变难了?(虽然自己都做出来了……) 场上预计得分:100+100+60~100+100+100+100=560~600(省一分数线365) 题解: D1T1 神奇的幻方 题面 ...

  6. [NOIP补坑计划]NOIP2013 题解&做题心得

    场上预计得分:100+100+100+100+100+60=560(省一分数线410) 五道傻逼题+一道大搜索题…… 题解: D1T1 转圈游戏 题面 水题送温暖~ #include<algor ...

  7. [NOIP补坑计划]NOIP2012 题解&做题心得

    场上预计得分:100+90+70+100+100+3060=490520(省一分数线245) 题解: D1T1 Vigenère 密码 题面 水题送温暖~~ #include<iostream& ...

  8. [NOIP补坑计划]NOIP2014 题解&做题心得

    六道普及组题,没啥好说的 场上预计得分:100+100+100+100+100+100=600(省一分数线490) (AK是不可能AK的,这辈子不可能AK的) 题解: D1T1 生活大爆炸版石头剪刀布 ...

  9. 标 题: [心得]传统IT转互联网面试经验分享

    发信人: lgonnet (逃之夭夭), 信区: Java标  题: [心得]传统IT转互联网面试经验分享发信站: 水木社区 (Wed Jul  1 10:18:38 2015), 站内 统一回复一下 ...

随机推荐

  1. Arduino IDE 开发ESP-01/ESP8266-01读取DHT11温度湿度传感器

    引脚接线: DHT11---ESP8266-01 Singnal--IO2, GND----GND, VCC----VCC DHT11引脚说明: ESP8266-01/ESP8266-01S引脚说明: ...

  2. http协议中的缓存机制

    强缓存 - expires,服务器给客户端一个过期日期,如(2020-12-12),过了该时间,客户端请求服务器重新获取.存在问题:客户端与服务端存在时间差,会导致过期时间不准确 - Cache-co ...

  3. maven版本仲裁原则

    这里有一个案例是项目里依赖了b组件,b组件依赖了a组件1.0.2版本,而用户也直接在pom依赖了a组件并声明的1.0.0版本,结果在仲裁时选择了1.0.0版本的a组件: +- com.xxx:a:ja ...

  4. 文本单词one-hot编码

    单词->字母->向量 神经网络是建立在数学的基础上进行计算的,因此对数字更敏感,不管是什么样的特征数据都需要以向量的形式喂入神经网络,无论是图片.文本.音频.视频都是一样. one-hot ...

  5. linux IP 注释

    DEVICE=name,这里name是物理设备的名字(动态分配的PPP设备应当除外,它的名字是"逻辑名". IPADDR=addr, 这里addr是IP地址. NETMASK=ma ...

  6. NP问题/NP完全问题(NP-complete problem)如何判断是否是NP完全问题

    在算法复杂度分析的过程中,人们常常用特定的函数来描述目标算法,随着变量n的增长,时间或者空间消耗的增长曲线,近而进一步分析算法的可行性(有效性). 引入了Big-O,Big-Ω,来描述目标算法的上限. ...

  7. NOIP初赛篇——03中央处理器CPU

    CPU ​ CPU(中央处理单元)是微机的核心部件,是决定微机性能的关键部件.20世纪70年代微型机的CPU问世,微型计算机的核心部件微处理器从Intel 4004,80286,80386,80486 ...

  8. 如何优雅地开发HarmonyOS APP应用

    目录: 一.挖掘项目需求或者做项目移植 二.创建项目工程 三.功能模块实现的流程思路 四.养成良好的编程规范习惯以及运用设计模式 研究HarmonyOS有一段时间了,今天主要结合自己多年的项目开发经验 ...

  9. Python在项目外更改项目内引用

    前言 目前有一个奇葩的需求, 将某个开源项目整合进自己的项目里去调度, 还需要在每次启动这个开源项目时, 加载不同的配置文件进去, 问题是配置文件并不是一个 conf 或者是其他的什么, 而是以 .p ...

  10. hugo建站 | 我的第一个博客网站

    前言 博客地址 - https://billie52707.cn 1. 建博客的初衷? 2020那一年,八月的第一天,我还是像往常一样打开我的域名网站,本以为还是会像以前一样显示每日一图的界面,结果出 ...