【BZOJ3712】Fiolki(并查集重构树)

题面

BZOJ

题解

很神仙的题目。
我们发现所有的合并关系构成了一棵树。
那么两种不同的东西如果产生反应,一定在两个联通块恰好联通的时候反应。
那么,我们按照并查集的合并顺序,类似于克鲁斯卡尔重构树的方法构建一个并查集重构树,
发现所有的反应恰好在两者的\(LCA\)处发生,
所以把所有可以发生的翻译拿出来,
按照\(LCA\)的深度为第一关键字,反应的优先级为第二关键字排序。
然后按顺序依次计算答案就好了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define RG register
#define MAX 500500
inline int read()
{RG int x=0,t=1;RG char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=-1,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*t;
}
ll ans;
int n,m,g[MAX],k;
struct Line{int v,next;}e[MAX];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int size[MAX],hson[MAX],top[MAX],fa[MAX],dep[MAX];
void dfs1(int u,int ff)
{dep[u]=dep[ff]+1;fa[u]=ff;size[u]=1;for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(v==ff)continue;dfs1(v,u);size[u]+=size[v];if(size[v]>size[hson[u]])hson[u]=v;}
}
void dfs2(int u,int tp)
{top[u]=tp;if(hson[u])dfs2(hson[u],tp);for(int i=h[u];i;i=e[i].next)if(e[i].v!=hson[u]&&e[i].v!=fa[u])dfs2(e[i].v,e[i].v);
}
int LCA(int u,int v)
{while(top[u]^top[v])dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];return dep[u]<dep[v]?u:v;
}
int f[MAX],tot;
struct Event{int dep,id,u,v;}p[MAX];
bool operator<(Event a,Event b)
{if(a.dep!=b.dep)return a.dep>b.dep;return a.id<b.id;
}
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int main()
{n=read();m=read();k=read();for(int i=1;i<=n;++i)g[i]=read(),f[i]=i;for(int i=1;i<=m;++i){int a=read(),b=read();Add(n+i,f[getf(a)]);Add(n+i,f[getf(b)]);f[getf(a)]=f[getf(b)]=n+i;f[n+i]=n+i;}for(int i=n+m;i;--i)if(!dep[i])dfs1(i,0),dfs2(i,i);for(int i=1;i<=k;++i){int u=read(),v=read();if(getf(u)!=getf(v))continue;int s=LCA(u,v);p[++tot]=(Event){dep[s],i,u,v};}sort(&p[1],&p[tot+1]);for(int i=1;i<=tot;++i){int u=p[i].u,v=p[i].v;int s=min(g[u],g[v]);ans+=s;g[u]-=s;g[v]-=s;}printf("%lld\n",ans+ans);
}

转载于:https://www.cnblogs.com/cjyyb/p/9368629.html

【BZOJ3712】Fiolki(并查集重构树)相关推荐

  1. 牛客 - 牛半仙的妹子图(并查集+bitset/克鲁斯卡尔重构树+主席树)

    题目链接:点击查看 题目大意:给出一个由 n 个点和 m 条边组成的连通图,每个点都有一种颜色,每条边都有一个权值,现在规定一个起点 st,再给出 q 次询问,每次询问给出区间 [ l , r ] , ...

  2. [NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)

    [NOI2018] 归程 description solution1 code1 solution2 code description 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要 ...

  3. 经典算法-并查集、快速排序、字典序算法、二分搜索、牛顿开方法、求质数(筛选法)、编辑距离、滑动窗口、异或求重、长除法

    目录 ​​​​​​​​​​​​​​ 并查集 快速排序 字典序算法 二分搜索 开根号-牛顿开方法 求质数 编辑距离 滑动窗口 异或求重 长除法 ​​​​​​​ 并查集 并查集用于解决相同元素集合动态连接 ...

  4. 图论 + 并查集 ----最小生成树重构图 + 可撤销并查集 + set启发式合并 时间线上的离线求解 D. Graph and Queries

    解题思路 题目大意: 就是给你一个无向图,每个点都有一个权值,和qqq次询问 每次询问有两种操作 1 x:就询问从x点出发,能访问到的最大权值是多少,并把最大权值那个点的权值设置为0 2 x:就是删除 ...

  5. 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]

    题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...

  6. CodeForces - 1417F Graph and Queries(克鲁斯卡尔重构树的dfs序上建线段树)

    题目链接:点击查看 题目大意:给出一个 n 个点 m 条边组成的无向图,每个点初始时都有一个权值 val,满足: 每个点的 val[ i ] 各不相同 val[ i ] ∈ [ 1 , n ] 现在有 ...

  7. 洛谷 - P4768 [NOI2018]归程(Kruskal重构树+树上倍增+最短路)

    题目链接:点击查看 题目大意:去原网址看吧 题目分析:因为是在刷克鲁斯卡尔重构树的题目,所以稍微思考一下就能想出解法了,首先如果水位线固定了,剩下的边组成的最小生成树也是一定的,此时同一个连通块内的点 ...

  8. 洛谷 - P4197 Peaks(Kruskal重构树+dfs序+主席树)

    题目链接:点击查看 题目大意:有 n 座山峰,每座山峰有他的高度 h[ i ] ,有些山峰之间有双向道路相连,共 m 条路径,每条路径有一个困难值,这个值越大表示越难走. 现在有 q 组询问,每组询问 ...

  9. 【NOI 2018】归程(Kruskal重构树)

    题面在这里就不放了. 同步赛在做这个题的时候,心里有点纠结,很容易想到离线的做法,将边和询问一起按水位线排序,模拟水位下降,维护当前的各个联通块中距离$1$最近的距离,每次遇到询问时输出所在联通块的信 ...

最新文章

  1. 惠普z840工作站linux,全模块战神 惠普旗舰级Z840工作站评测
  2. 一些关于人工智能的讨论(二)
  3. CheXNet 肺炎
  4. Android进阶:六、在子线程中直接使用 Toast 及其原理
  5. C#窗体之间事件传值
  6. 后台系统可扩展性学习笔记(七)Service Discovery与微服务
  7. Github项目汇总
  8. Git missing Change-Id in commit message footer解决方法
  9. bzoj 1207: [HNOI2004]打鼹鼠【dp】
  10. Anlink中文版(免费安卓投屏软件)官方正式版V3.0 | 优秀的电脑控制手机软件 | anlink官网下载
  11. HMM和DNN语音合成必备基础知识:音素和拼音的基础知识及工具初学
  12. 如何学习计算机组成原理
  13. 小白简单式安装VM虚拟机
  14. etcd教程(二)—clientv3简单使用
  15. Unity3d开发MOBA游戏类《王者荣耀》记录(起)
  16. Linux下用命令行彻底删除文件
  17. api工厂接口路径是什么_为什么(几乎)永远不要再使用绝对路径访问API
  18. 小程序开发笔记(二):微信小程序富文本编辑器editor的使用
  19. 机器人相关专家研究机构
  20. sku与spu 概念

热门文章

  1. java putall实现,Java EnumMap putAll()
  2. 【sprinb-boot】@ComponentScan 使用
  3. 【SSL】java keytool工具操作PCKS12证书库
  4. java守护线程和用户线程
  5. html美化计算机,职称计算机Dreamwaver教程:CSS样式表滤镜
  6. python累积和_python – 如何维持累积总和?
  7. 计算机在线采集数据注意,全站仪数据采集和传输中的常见问题解决方案
  8. python 图片旋转角度_OpenCV获取图像的旋转角度
  9. 开发商微信选房后不退认筹金_网曝!青岛恒大文化旅游城1400余名购房者欲退认筹金,开发商表示.........
  10. mysql驱动_python3 接口测试数据驱动之操作mysql数据库