题目:luogu4234.
题目大意:给定一张nnn个点mmm条边无向图,求这张无向图最大边和最小边的最小权值差.
1≤n≤5∗104,1≤m≤2∗1051\leq n\leq 5*10^4,1\leq m\leq 2*10^51≤n≤5∗104,1≤m≤2∗105.

首先,我们明确一点,一棵最小生成树上的最大边一定最小,这一点很容易用kruskal的算法流程来证明.

那么我们就可以考虑一个暴力算法,枚举一棵生成树的最小边,然后依照kruskal算法加入剩下的边来组成生成树,取最优即可.时间复杂度O(m2log⁡n)O(m^2\log n)O(m2logn).

考虑如何优化这个算法,我们发现枚举的过程不太可能去掉,并查集的时间复杂度去掉没有多大意义,所以我们选择优化每一棵生成树的生成过程.

我们考虑,当我们枚举到一条边时,若我们当前维护的边集中加入这条边不会形成环,我们就将这条边加入.否则我们找到一条形成的环上边权最小的边,然后删掉这条边加入当前的边.当我们维护的边集组成一棵生成树的时候,我们就可以更新答案.

那么我们考虑一棵LCT来维护这道题的这棵带删除和查询链上最小值的并查集即可.

至于维护边权的LCT,拆点维护即可.

代码如下:

#include<bits/stdc++.h>using namespace std;
#define Abigail inline void
const int N=50000,M=200000,INF=1<<29;
struct tree{int x,min,g,fa,s[2],rev;
}tr[N+M+9];
int tmp[N+M+9],ttmp;
int n,m,ans=INF,use[M+9];
struct side{int x,y,v;bool operator < (const side &p)const{return v<p.v;}
}e[M+9];
bool Isroot(int x){return tr[tr[x].fa].s[0]^x&&tr[tr[x].fa].s[1]^x;}
void Pushup(int x){int ls=tr[x].s[0],rs=tr[x].s[1];if (tr[ls].min<tr[rs].min&&tr[ls].min<tr[x].x) tr[x].min=tr[ls].min,tr[x].g=tr[ls].g;else if (tr[rs].min<tr[x].x) tr[x].min=tr[rs].min,tr[x].g=tr[rs].g;else tr[x].min=tr[x].x,tr[x].g=x;
}
void Update_rev(int x){tr[x].rev^=1;swap(tr[x].s[0],tr[x].s[1]);}
void Pushdown(int x){if (!tr[x].rev) return;tr[x].rev=0;Update_rev(tr[x].s[0]);Update_rev(tr[x].s[1]);
}
void Rotate(int x){int y=tr[x].fa,z=tr[y].fa,k=tr[y].s[1]==x;if (!Isroot(y)) tr[z].s[tr[z].s[1]==y]=x;tr[x].fa=z;tr[y].s[k]=tr[x].s[k^1];if (tr[x].s[k^1]) tr[tr[x].s[k^1]].fa=y;tr[x].s[k^1]=y;tr[y].fa=x;Pushup(y);Pushup(x);
}
void Splay(int x){int y,z;tmp[ttmp=1]=x;for (int i=x;!Isroot(i);i=tr[i].fa) tmp[++ttmp]=tr[i].fa;for (;ttmp;ttmp--) Pushdown(tmp[ttmp]);while (!Isroot(x)){y=tr[x].fa,z=tr[y].fa;if (!Isroot(y)) tr[y].s[1]==x^tr[z].s[1]==y?Rotate(x):Rotate(y);Rotate(x);}Pushup(x);
}
void Access(int x){for (int t=0;x;t=x,x=tr[x].fa)Splay(x),tr[x].s[1]=t,Pushup(x);
}
void Makeroot(int x){Access(x);Splay(x);Update_rev(x);}
int Root(int x){Access(x);Splay(x);while (tr[x].s[0]) x=tr[x].s[0];return x;}
void Split(int x,int y){Makeroot(x);Access(y);Splay(y);}
void Link(int x,int y){if (Root(x)==Root(y)) return;Makeroot(x);tr[x].fa=y;}
void Cut(int x,int y){Split(x,y);if (tr[y].s[0]^x||tr[y].s[1]||tr[x].s[1]) return;tr[y].s[0]=tr[x].fa=0;}
int Query_g(int x,int y){Split(x,y);return tr[y].g;}
Abigail into(){scanf("%d%d",&n,&m);for (int i=0;i<=n;i++) tr[i].x=tr[i].min=INF;for (int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);
}
Abigail work(){sort(e+1,e+1+m);int h=1,cnt=1;for (int i=1;i<=m;i++) tr[i+n].x=e[i].v;for (int i=1;i<=m;i++)if (Root(e[i].x)^Root(e[i].y)){Link(e[i].x,i+n);Link(e[i].y,i+n);use[i]=1;while (!use[h]) ++h;if (++cnt==n) ans=min(ans,e[i].v-e[h].v);}else{if (e[i].x==e[i].y) continue;int g=Query_g(e[i].x,e[i].y)-n;Cut(e[g].x,g+n);Cut(e[g].y,g+n);use[g]=0;Link(e[i].x,i+n);Link(e[i].y,i+n);use[i]=1;while (!use[h]) ++h;if (cnt==n) ans=min(ans,e[i].v-e[h].v);}
}
Abigail outo(){printf("%d\n",ans);
}
int main(){into();work();outo();return 0;
}

洛谷4234最小差值生成树题解(最小生成树+LCT)相关推荐

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

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

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

    给定一个标号为从$1$到$n$的.有$m$条边的无向图,求边权最大值与最小值的差值最小的生成树. 做法类似魔法森林,首先求出来最小生成树,然后每次加入一条边,断掉环上最小边并更新答案 这个过程我用两个 ...

  3. 洛谷P5633 最小度限制生成树 题解

    洛谷P5633 最小度限制生成树 题解 题目链接:P5633 最小度限制生成树 题意: 给你一个有 n n n 个节点, m m m 条边的带权无向图,你需要求得一个生成树,使边权总和最小,且满足编号 ...

  4. 洛谷P2619 [国家集训队]Tree I 题解

    洛谷P2619 [国家集训队]Tree I 题解 题目链接:P2619 [国家集训队]Tree I 题意: 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有 need\text{n ...

  5. 洛谷P1282 多米诺骨牌 题解

    洛谷P1282 多米诺骨牌 题解 题目链接:P1282 多米诺骨牌 题意: 多米诺骨牌由上下 222 个方块组成,每个方块中有 1∼61\sim61∼6 个点.现有排成行的上方块中点数之和记为 S1S ...

  6. 洛谷P3237 [HNOI2014]米特运输 题解

    洛谷P3237 [HNOI2014]米特运输 题解 题目链接:P3237 [HNOI2014]米特运输 题意: 这题面是真的长啊 qwq 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为 ...

  7. 洛谷P5520 [yLOI2019] 青原樱 题解

    洛谷P5520 [yLOI2019] 青原樱 题解 题目链接:P5520 [yLOI2019] 青原樱 题意: n n n 个空放 m m m 个物品,两两物品不能直接相邻,至少空一格 纯数学题. 看 ...

  8. 洛谷P4084 [USACO17DEC]Barn Painting G 题解

    洛谷P4084 [USACO17DEC]Barn Painting G 题解 题目链接:P4084 [USACO17DEC]Barn Painting G 题意:题意:给定一颗N个节点组成的树,3种颜 ...

  9. 洛谷P4315 月下“毛景树” 题解

    洛谷P4315 月下"毛景树" 题解 题目链接:P4315 月下"毛景树" 题意:请维护一个数据结构,支持 改第 kkk 条边的边权 结点 uuu 到 vvv ...

  10. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

最新文章

  1. 据说中台凉了?唔,真香
  2. 推荐一个比较好的SQL工具——SQL Prompt
  3. 漫画:通俗易懂的进程与线程解释
  4. OPPO A59s手机系统时间停止运行
  5. JavaScript —— this、闭包、原型、异步
  6. HDU 4893 - Wow! Such Sequence!(线段树)
  7. c++ 预处理命令 #undef用法
  8. spring boot 使用视图modelandview
  9. linux卸载minicoda2,MiniConda2下载 MiniConda python 2.7 v4.3.30.2 Linux 64位 官方免费版(附安装步骤) 下载-脚本之家...
  10. c语言 增删查 案例,C语言实现单链表的增删查改
  11. python中网页关闭再打开_Python Selenium 之关闭窗口close与quit的方法
  12. ELK学习笔记之Logstash详解
  13. 关于visio你必须要知道的一些小技巧
  14. vs2015 下配置sfml
  15. Codeforces Round #342 (Div. 2) D. Finals in arithmetic(想法题/构造题)
  16. Android低功耗蓝牙通讯
  17. 0X000000该内存不能为read的解决方法(转)
  18. DoubanFm之设计模式(一)
  19. python做excel自动化视频教程-从零基础入门到精通用Python处理Excel数据视频教程...
  20. ATMel的AT89C52芯片慎选

热门文章

  1. 【SandQuant 量化投资】哈里·马科维茨:投资组合的选择
  2. 编辑器、编译器以及IDE
  3. 各类对象属性拷贝工具性能测试对比(BeanCopier、BeanUtils、DozerBeanMapper、PropertyUtils)
  4. [老文档2016]一种后台管理智能杀进程的规则与方法
  5. 让python pip使用国内镜像安装模块
  6. amoeba mysql读写分离_MySQL和Amoeba实现同步读写分离centos7
  7. Google发布免费的SketchUp
  8. 采样频率Hz 采样率KSPS或MSPS,两种单位的换算关系
  9. 联想电脑重装系统F12开机项选择无USB启动选项
  10. UG NX二次开发 - CAM 获取和设置公差的方法,含内外公差、边界内外公差的设置方法