正题

题目链接:https://www.luogu.com.cn/problem/P4234


题目大意

给出\(n\)个点\(m\)条边的一张图。求一棵生成树使得最大边权减去最小边权最小。

\(1\leq n\leq 5\times 10^4,1\leq m\leq 2\times 10^5\)


解题思路

按照边权排序,然后像魔法森林一样用\(LCT\)维护最小生成树就好了。

没啥别的,练练手而已。时间复杂度\(O(n\log n)\)


code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<stack>
  5. using namespace std;
  6. const int N=3e5+10;
  7. struct node{
  8. int x,y,w;
  9. }e[N];
  10. int n,m,p[N],fa[N];bool v[N];
  11. struct LCT{
  12. int fa[N],t[N][2];
  13. bool r[N];stack<int> s;
  14. bool Nroot(int x)
  15. {return fa[x]&&(t[fa[x]][0]==x||t[fa[x]][1]==x);}
  16. bool Direct(int x)
  17. {return t[fa[x]][1]==x;}
  18. void PushUp(int x)
  19. {p[x]=min(min(p[t[x][0]],p[t[x][1]]),x);return;}
  20. void Rev(int x)
  21. {r[x]^=1;swap(t[x][0],t[x][1]);return;}
  22. void PushDown(int x)
  23. {if(r[x])Rev(t[x][0]),Rev(t[x][1]),r[x]=0;return;}
  24. void Rotate(int x){
  25. int y=fa[x],z=fa[y];
  26. int xs=Direct(x),ys=Direct(y);
  27. int w=t[x][xs^1];
  28. t[y][xs]=w;t[x][xs^1]=y;
  29. if(Nroot(y))t[z][ys]=x;
  30. if(w)fa[w]=y;fa[y]=x;fa[x]=z;
  31. PushUp(y);PushUp(x);return;
  32. }
  33. void Splay(int x){
  34. int y=x;s.push(x);
  35. while(Nroot(y))y=fa[y],s.push(y);
  36. while(!s.empty())PushDown(s.top()),s.pop();
  37. while(Nroot(x)){
  38. int y=fa[x];
  39. if(!Nroot(y))Rotate(x);
  40. else if(Direct(x)==Direct(y))
  41. Rotate(y),Rotate(x);
  42. else Rotate(x),Rotate(x);
  43. }
  44. return;
  45. }
  46. void Access(int x){
  47. for(int y=0;x;y=x,x=fa[x])
  48. Splay(x),t[x][1]=y,PushUp(x);
  49. return;
  50. }
  51. void MakeRoot(int x)
  52. {Access(x);Splay(x);Rev(x);return;}
  53. int Split(int x,int y)
  54. {MakeRoot(x);Access(y);Splay(y);return p[y];}
  55. void Link(int x,int y)
  56. {MakeRoot(x);fa[x]=y;Access(x);return;}
  57. void Cut(int x,int y)
  58. {MakeRoot(x);Access(y);Splay(y);fa[t[y][0]]=0;t[y][0]=0;PushUp(y);return;}
  59. }T;
  60. int find(int x)
  61. {return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
  62. bool cmp(node x,node y)
  63. {return x.w<y.w;}
  64. int main()
  65. {
  66. scanf("%d%d",&n,&m);
  67. for(int i=1;i<=m;i++)
  68. scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
  69. sort(e+1,e+1+m,cmp);
  70. memset(p,0x3f,sizeof(p));
  71. for(int i=1;i<=n+m;i++)fa[i]=p[i]=i;
  72. int k=n,z=0,ans=1e5;
  73. for(int i=1;i<=m;i++){
  74. int x=e[i].x,y=e[i].y;
  75. if(x==y)continue;
  76. int fx=find(x),fy=find(y);
  77. if(fx==fy){
  78. int num=T.Split(x+m,y+m);
  79. T.Cut(e[num].x+m,num);
  80. T.Cut(num,e[num].y+m);
  81. v[num]=0;
  82. }
  83. else fa[fx]=fy,k--;
  84. T.Link(x+m,i);T.Link(i,y+m);
  85. v[i]=1;while(!v[z])z++;
  86. if(k==1)ans=min(ans,e[i].w-e[z].w);
  87. }
  88. printf("%d\n",ans);
  89. return 0;
  90. }

P4234-最小差值生成树【LCT】的更多相关文章

  1. P4234 最小差值生成树 LCT维护边权

    \(\color{#0066ff}{ 题目描述 }\) 给定一个标号为从 \(1\) 到 \(n\) 的.有 \(m\) 条边的无向图,求边权最大值与最小值的差值最小的生成树. \(\color{#0 ...

  2. 洛谷 P4234 最小差值生成树(LCT)

    题面 luogu 题解 LCT 动态树Link-cut tree(LCT)总结 考虑先按边权排序,从小到大加边 如果构成一颗树了,就更新答案 当加入一条边,会形成环. 贪心地想,我们要最大边权-最小边 ...

  3. P4234 最小差值生成树

    题目 P4234 最小差值生成树 做法 和这题解法差不多,稍微变了一点,还不懂就直接看代码吧 \(update(2019.2):\)还是具体说一下吧,排序,直接加入,到了成环情况下,显然我们要把此边代 ...

  4. 洛谷.4234.最小差值生成树(LCT)

    题目链接 先将边排序,这样就可以按从小到大的顺序维护生成树,枚举到一条未连通的边就连上,已连通则(用当前更大的)替换掉路径上最小的边,这样一定不会更差. 每次构成树时更新答案.答案就是当前边减去生成树 ...

  5. 洛谷P4234 最小差值生成树(lct动态维护最小生成树)

    题目描述 给定一个标号为从 11 到 nn 的.有 mm 条边的无向图,求边权最大值与最小值的差值最小的生成树. 输入输出格式 输入格式:   第一行两个数 n, mn,m ,表示图的点和边的数量. ...

  6. 【Luogu】P4234最小差值生成树(LCT)

    题目链接 能把LCT打得每个函数都恰有一个错误也是挺令我惊讶的. 本题使用LCT维护生成树,具体做法是对原图中的每个边建一个点,然后连边的时候相当于是将边的起点跟“边”这个点连起来,边的终点也跟它连起 ...

  7. 洛谷P4234 最小差值生成树(LCT,生成树)

    洛谷题目传送门 和魔法森林有点像,都是动态维护最小生成树(可参考一下Blog的LCT总结相关部分) 至于从小到大还是从大到小当然无所谓啦,我是从小到大排序,每次枚举边,还没连通就连,已连通就替换环上最 ...

  8. 【刷题】洛谷 P4234 最小差值生成树

    题目描述 给定一个标号为从 \(1\) 到 \(n\) 的.有 \(m\) 条边的无向图,求边权最大值与最小值的差值最小的生成树. 输入输出格式 输入格式: 第一行两个数 \(n, m\) ,表示图的 ...

  9. Luogu P4234 最小差值生成树

    题意 给定一个 \(n\) 个点 \(m\) 条边的有权无向图,求出原图的一棵生成树使得该树上最大边权与最小边权的差值最小. \(\texttt{Data Range:}1\leq n\leq 5\t ...

  10. [洛谷P4234] 最小差值生成树

    题目类型:\(LCT\)动态维护最小生成树 传送门:>Here< 题意:求一棵生成树,其最大边权减最小边权最小 解题思路 和魔法森林非常像.先对所有边进行排序,每次加边的时候删除环上的最小 ...

随机推荐

  1. visual studio code 中文

    1.按住ctrl+shift+p键,在框中输入configure,在下拉选项中选取language选项 2.打开locale.json文件,修改语言配置 3.修改完保存,然后重新启动vscode 4. ...

  2. MySQL——分表,分库操作

    说明 大数据量并且访问频繁的表,将其分为若干个表.如果不分的话,进行一次查询就会将表锁住,导致不能进行其他操作,故分表.表分割垂直分割应用场景:热数据放一个表里,冷数据放一个表里.冷数据使用MyIsa ...

  3. springboot与通用mapper的整合

    找到springboot工程下的pom.xml文件,导入如下的依赖jar包 <!--配置通用Mapper start--> <dependency> <groupId&g ...

  4. UWP使用命名管道与桌面程序通信 (C#)

    关于UWP的历史,其起源是Microsoft在Windows 8中引入的Metro apps.(后来又被称作Modern apps, Windows apps, Universal Windows A ...

  5. 原生 JS 与 jQuery 中的 AJAX

    AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更 ...

  6. redis BLPOP命令阻塞,非阻塞(读了好久才懂)

    来源于:http://redisdoc.com/list/blpop.html#id1BLPOP key [key -] timeout 可用版本: >= 2.0.0 时间复杂度: O(1) B ...

  7. Java动态代理底层实现

    Java实现源码 上一节我们提到了Java动态代理的使用,接下来我们看一下他的具体实现. HelloInterface proxyHello = (HelloInterface) Proxy.newP ...

  8. ubuntu下使用minicom

    环境 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL 安装及使用 首先时在Ubuntu里安装minicom sudo apt-get install minicom 接下来可以使用 ...

  9. openswan中的in_struct和out_struct函数

    openswan中的in_struct和out_struct函数 文章目录 openswan中的in_struct和out_struct函数 1. 花絮 2. in_struct代码实现分析 3. 它 ...

  10. docker的网络基础

    docker使用的与Linux网络有关的主要技术: Network Namespace Veth 设备对 Iptables/Netfilter 网桥 路由 <1> 网络命令空间 names ...