圆方树总结

所谓圆方树就是把一张图变成一棵树。

怎么变啊qaq

这里盗一张图



简单来说就是给每一个点双新建一个点,然后连向这个点双中的每一个点。特殊的,把两个点互相连通的也视作一个点双。

我们把原来就有的点称作圆点,因点双而新建的点称之为方点。

这样这棵圆方树就会有一个这样的性质:和每个圆点(方点)相连的点一定是方点(圆点)。

我们在每个圆点上维护这个点原本的信息,在方点上维护这个点双的信息,这样就能完成一些关于一般图的所有简单路径的询问了。

例如:我现在有一张一般图,每个点有一个点权,要求从\(u\)到\(v\)的所有简单路径中经过的最小点权是多少。

可以建出圆方树,在每个方点上维护这个点双中的最小点权,那么每次询问就是查询一个路径最小值了。

如果有修改怎么办呢?直接改完圆点后改和它相邻的方点?

显然这个复杂度是\(O(度数)\)的,很容易卡成\(O(n^2)\)

方法:每个方点维护的信息中不包括它的父亲圆点,这样修改圆点的时候就只需要修改它的父亲方点。查询的时候如果路径的\(lca\)是个方点,就还要再算上它的父亲圆点。

是不是很妙?

uoj30

就是上面讲的那个东西。

圆方树+可删除堆+树链剖分+线段树

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<queue>
  5. using namespace std;
  6. int gi(){
  7. int x=0,w=1;char ch=getchar();
  8. while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  9. if (ch=='-') w=0,ch=getchar();
  10. while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
  11. return w?x:-x;
  12. }
  13. const int N = 4e5+5;
  14. int n,tot,m,q,val[N],dfn[N],low[N],tim,S[N];
  15. int fa[N],dep[N],sz[N],son[N],top[N],mn[N<<2];
  16. struct Set{
  17. priority_queue<int,vector<int>,greater<int> >Q1,Q2;
  18. void insert(int x){Q1.push(x);}
  19. void erase(int x){Q2.push(x);}
  20. int top(){
  21. while (!Q2.empty()&&Q1.top()==Q2.top()) Q1.pop(),Q2.pop();
  22. return Q1.top();
  23. }
  24. }Q[N];
  25. struct Graph{
  26. int to[N],nxt[N],head[N],cnt;
  27. void link(int u,int v){
  28. to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
  29. to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;
  30. }
  31. }G1,G2;
  32. void Tarjan(int u){
  33. dfn[u]=low[u]=++tim;S[++S[0]]=u;
  34. for (int e=G1.head[u];e;e=G1.nxt[e]){
  35. int v=G1.to[e];
  36. if (!dfn[v]){
  37. Tarjan(v),low[u]=min(low[u],low[v]);
  38. if (low[v]>=dfn[u]){
  39. G2.link(++tot,u);int x=0;
  40. do{
  41. x=S[S[0]--];G2.link(tot,x);
  42. }while (x!=v);
  43. }
  44. }
  45. else low[u]=min(low[u],dfn[v]);
  46. }
  47. }
  48. void dfs1(int u,int f){
  49. fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
  50. if (u<=n&&f) Q[f].insert(val[u]);
  51. for (int e=G2.head[u];e;e=G2.nxt[e]){
  52. int v=G2.to[e];if (v==f) continue;
  53. dfs1(v,u);sz[u]+=sz[v];
  54. if (sz[v]>sz[son[u]]) son[u]=v;
  55. }
  56. }
  57. void dfs2(int u,int up){
  58. top[u]=up;dfn[u]=++tim;
  59. if (son[u]) dfs2(son[u],up);
  60. for (int e=G2.head[u];e;e=G2.nxt[e]){
  61. int v=G2.to[e];if (v==fa[u]||v==son[u]) continue;
  62. dfs2(v,v);
  63. }
  64. }
  65. void modify(int x,int l,int r,int p,int v){
  66. if (l==r) {mn[x]=v;return;}
  67. int mid=l+r>>1;
  68. if (p<=mid) modify(x<<1,l,mid,p,v);
  69. else modify(x<<1|1,mid+1,r,p,v);
  70. mn[x]=min(mn[x<<1],mn[x<<1|1]);
  71. }
  72. int query(int x,int l,int r,int ql,int qr){
  73. if (l>=ql&&r<=qr) return mn[x];
  74. int mid=l+r>>1;
  75. if (qr<=mid) return query(x<<1,l,mid,ql,qr);
  76. if (ql>mid) return query(x<<1|1,mid+1,r,ql,qr);
  77. return min(query(x<<1,l,mid,ql,qr),query(x<<1|1,mid+1,r,ql,qr));
  78. }
  79. int main(){
  80. tot=n=gi();m=gi();q=gi();
  81. for (int i=1;i<=n;++i) val[i]=gi();
  82. while (m--){
  83. int u=gi(),v=gi();
  84. G1.link(u,v);
  85. }
  86. for (int i=1;i<=n;++i) if (!dfn[i]) Tarjan(i);
  87. tim=0;dfs1(1,0),dfs2(1,1);
  88. for (int i=1;i<=n;++i) modify(1,1,tot,dfn[i],val[i]);
  89. for (int i=n+1;i<=tot;++i) modify(1,1,tot,dfn[i],Q[i].top());
  90. while (q--){
  91. char ch='%';while (ch!='A'&&ch!='C') ch=getchar();
  92. if (ch=='C'){
  93. int a=gi(),b=gi();
  94. if (fa[a]) Q[fa[a]].erase(val[a]);
  95. val[a]=b;modify(1,1,tot,dfn[a],val[a]);
  96. if (fa[a]) Q[fa[a]].insert(val[a]),modify(1,1,tot,dfn[fa[a]],Q[fa[a]].top());
  97. }
  98. else{
  99. int u=gi(),v=gi(),ans=2e9;
  100. while (top[u]^top[v]){
  101. if (dep[top[u]]<dep[top[v]]) swap(u,v);
  102. ans=min(ans,query(1,1,tot,dfn[top[u]],dfn[u]));
  103. u=fa[top[u]];
  104. }
  105. if (dep[u]>dep[v]) swap(u,v);
  106. ans=min(ans,query(1,1,tot,dfn[u],dfn[v]));
  107. if (u>n) ans=min(ans,val[fa[u]]);
  108. printf("%d\n",ans);
  109. }
  110. }
  111. return 0;
  112. }

圆方树与仙人掌

留坑待补

圆方树总结 [uoj30]Tourists的更多相关文章

  1. 【学习笔记】圆方树(CF487E Tourists)

    终于学了圆方树啦~\(≧▽≦)/~ 感谢y_immortal学长的博客和帮助 把他的博客挂在这里~ 点我传送到巨佬的博客QwQ! 首先我们来介绍一下圆方树能干什么呢qwq 1.将图上问题简化到树上问题 ...

  2. 圆方树简介(UOJ30:CF Round #278 Tourists)

    我写这篇博客的原因 证明我也是学过圆方树的 顺便存存代码 前置技能 双联通分量:点双 然后就没辣 圆方树 建立 新建一个图 定义原图中的所有点为圆点 对于每个点双联通分量(只有两个点的也算) 建立一个 ...

  3. uoj30【CF Round #278】Tourists(圆方树+树链剖分+可删除堆)

    - 学习了一波圆方树 学习了一波点分治 学习了一波可删除堆(巧用 ? STL) 传送门: Icefox_zhx 注意看代码看怎么构建圆方树的. tips:tips:tips:圆方树内存记得开两倍 CO ...

  4. 【CF487E】Tourists(圆方树)

    [CF487E]Tourists(圆方树) 题面 UOJ 题解 首先我们不考虑修改,再来想想这道题目. 我们既然要求的是最小值,那么,在经过一个点双的时候,走的一定是具有较小权值的那一侧. 所以说,我 ...

  5. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  6. Tourists——圆方树

    CF487E Tourists 一般图,带修求所有简单路径代价. 简单路径,不能经过同一个点两次,那么每个V-DCC出去就不能再回来了. 所以可以圆方树,然后方点维护一下V-DCC内的最小值. 那么, ...

  7. CF487E Tourists(圆方树+树链剖分+multiset/可删堆)

    CF487E Tourists(圆方树+树链剖分+multiset/可删堆) Luogu 给出一个带点权的无向图,两种操作: 1.修改某点点权. 2.询问x到y之间简单路径能走过的点的最小点权. 题解 ...

  8. Codeforces 487E Tourists [广义圆方树,树链剖分,线段树]

    洛谷 Codeforces 思路 首先要莫名其妙地想到圆方树. 建起圆方树后,令方点的权值是双联通分量中的最小值,那么\((u,v)\)的答案就是路径\((u,v)\)上的最小值. 然而这题还有修改, ...

  9. CF487E Tourists 圆方树、树链剖分

    传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ...

随机推荐

  1. a4纸尺寸像素大小

    A4纸尺寸:210mm*297mm,也就是21.0cm*29.7cm,而1英寸=2.54cm.如果在PS中新建为72像素/英寸的画布,大小为A4尺寸,经过换算就是:(72px/2.54cm) = 28 ...

  2. 阿里云服务器: centos7 ftp安装

    阿里云服务器: centos7 ftp安装 ftp需要您参考下面链接和附件开放安全组20.21.1024-65535 后查看是否正常. 配置步骤如下, 1, 如果没有安装ftp,需要先安装 yum - ...

  3. PHP memcache扩展模块安装

    安装php扩展模块memcache memcache 的工作就是在专门的机器的内存里维护一张巨大的hash表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率,减轻后端数据库的读写压力. ...

  4. shell-最近7天目录

    #采用将最近7天的日期放入到数组中,遍历整个目录,将这7天的目录连接成一个字符串paths. #注意: .日期目录里面的文件只是做了简单的以part开头的匹配. # .path路径是日期的上一层,以/ ...

  5. Python 面向对象的三大特性:封装,继承,多态

    # 面向对象的三大特性:封装,继承,多态 # 继承的影响:资源的继承,资源的使用,资源的覆盖,资源的累加 # 资源的继承,在Python中的继承是指能使用父类的资源,而不是说在子类也复制一份父类代码到 ...

  6. LeetCode——Add Strings

    LeetCode--Add Strings Question Given two non-negative integers num1 and num2 represented as string, ...

  7. java关键词整理——思维导图

    如图 思维导图图片链接 http://www.edrawsoft.cn/viewer/public/s/5e27f174483042

  8. FZU 1759 Super A^B mod C 指数循环节

    Problem 1759 Super A^B mod C Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description G ...

  9. Spark- JdbcRDD以及注意事项

    先上Demo package com.rz.spark.base import java.sql.DriverManager import org.apache.spark.rdd.JdbcRDD i ...

  10. angular 图片懒加载(延迟加载)

    github 原文 https://github.com/Treri/me-lazyload me-lazyload angular 的图像资源延迟加载指令 例子(Demo) 演示网站(Demo Si ...