题目链接

先将边排序,这样就可以按从小到大的顺序维护生成树,枚举到一条未连通的边就连上,已连通则(用当前更大的)替换掉路径上最小的边,这样一定不会更差。
每次构成树时更新答案。答案就是当前边减去生成树上最小边的权值。
LCT上维护最小边的编号。求最小边把树上的边用vis[]标记即可。

不熟啊.

(另外暴力可以排序后枚举一个分界点,在它之后求最小生成树,在它之前求最大生成树)

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define INF 10000007
const int N=5e4+5,M=2e5+5,S=N+M;int n,m,_fa[N];
bool vis[M];
struct Edge
{int fr,to,val;Edge() {}Edge(int f,int t,int v): fr(f),to(t),val(v) {}bool operator <(const Edge &a)const {return val<a.val;}
}e[M];
namespace LCT
{#define lson son[x][0]#define rson son[x][1]int fa[S],son[S][2],sk[S],pos[S],val[S];bool tag[S];inline int Get(int x,int y){//取最小的边 return val[x]<val[y]?x:y;}inline void Update(int x){pos[x]=Get(x,Get(pos[lson],pos[rson]));//是左右儿子的最小边pos[]!}inline bool n_root(int x){return son[fa[x]][0]==x||son[fa[x]][1]==x;}inline void Rev(int x){std::swap(lson,rson), tag[x]^=1;}void PushDown(int x){if(tag[x]) Rev(lson),Rev(rson),tag[x]=0;}void Rotate(int x){int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;if(n_root(a)) son[b][son[b][1]==a]=x;if(son[x][r]) fa[son[x][r]]=a;fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;Update(a);}void Splay(int x){int t=1,a=x; sk[1]=x;while(n_root(a)) sk[++t]=a=fa[a];while(t) PushDown(sk[t--]);while(n_root(x)){if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);Rotate(x);}Update(x);}void Access(int x){for(int pre=0; x; x=fa[pre=x])Splay(x), rson=pre, Update(x);}void Make_root(int x){Access(x), Splay(x), Rev(x);}void Split(int x,int y){Make_root(x), Access(y), Splay(y);}void Link(int x){Make_root(e[x].to), fa[fa[e[x].to]=x+N]=e[x].fr;}void Cut(int x){Access(e[x-N].to), Splay(x), lson=rson=fa[lson]=fa[rson]/*=fa[x]*/=0;//fa[x]应该是用不到吧。。注意更新顺序!后更新lson,rson...}
}
using namespace LCT;inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
int Get_fa(int x){return x==_fa[x]?x:_fa[x]=Get_fa(_fa[x]);
}int main()
{n=read(),m=read();val[0]=INF;//空节点!for(int i=1; i<=n; ++i) _fa[i]=i, val[i]=INF;//点有自己的权值,设为INF避免影响答案(最小边) for(int u,v,w,i=1; i<=m; ++i) u=read(),v=read(),w=read(),e[i]=Edge(u,v,w);std::sort(e+1,e+1+m);
//  for(int i=1; i<=m; ++i) val[i+N]=e[i].val;int res=1e6;for(int p=1,x,y,k=1,i=1; i<=m; ++i){val[i+N]=e[i].val, x=e[i].fr, y=e[i].to;if(k<n && Get_fa(x)!=Get_fa(y)){_fa[_fa[x]]=_fa[y];//路径压缩后 Link(i), vis[i]=1;if(++k>=n) res=e[i].val-e[p].val;}else if(x!=y)//不要计算重边 {Split(x,y);vis[pos[y]-N]=0, vis[i]=1;//别忘了Splay(y)后再用y的信息pos[y]!而且要先用pos[y]清vis再Cut().while(!vis[p]) ++p;Cut(pos[y]), Link(i);if(k>=n) res=std::min(res,e[i].val-e[p].val);}}printf("%d",res);return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/8637929.html

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

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

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

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

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

  3. 洛谷3613睡觉困难综合征(LCT维护链信息(前后缀)+贪心)

    这个题目还是很好啊QWQ很有纪念意义 首先,如果在序列上且是单次询问的话,就是一个非常裸的贪心了QWQ这也是NOI当时原题的问题和数据范围 我们考虑上树的话,应该怎么做? 我的想法是,对于每一位建一个 ...

  4. 洛谷 p2387 [noi2014] 膜fa♂森林 lct维护最小生成树

    题目简述 做法 题目简述 求1-n的一条路径,路径上所有边的a的最大值和b的最大值相加最小. 做法 首先把边按照 a a a的大小排序,接下来用link_cut_tree维护1→n" rol ...

  5. 洛谷 1351 联合权值

    [题解] 每个点维护各个儿子的前后缀最大值.权值和,这样就可以统计儿子之间相乘的答案.然后每个节点再乘它的祖父的权值去更新答案即可. 1 #include<cstdio> 2 #inclu ...

  6. 【洛谷P4719】动态DP【LCT】【矩阵】

    之前的后缀平衡树其实没完,只是过于鬼畜就弃了 传送门 题意:带修改点权的最大独立集 N≤1e5N \leq 1e5N≤1e5 一个没啥用的模板,不过适合练习LCT 先写出方程 f(u,0)=∑v∈so ...

  7. YBTOJ洛谷P2387: 魔法森林(LCT)

    解析 LCT从板子到算法的入门题吧 有一些不知道的很实用的技巧 把边按a排序从小到大加入边 那么我们只需要维护当前1-n路径上的b的最小值即可 如果这条边两端点本来不连通,就直接link 否则找到路径 ...

  8. 洛谷P1351 联合权值(树形dp)

    题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...

  9. 洛谷 1351 联合权值——树形dp

    题目:https://www.luogu.org/problemnew/show/P1351 对拍了一下,才发现自己漏掉了那种拐弯的情况. #include<iostream> #incl ...

最新文章

  1. jQuery 中的 Ajax
  2. 不是之所以不是,所以不是
  3. 【数学基础】拉格朗日乘子法
  4. python配置opencv镜像安装
  5. STM32之SPI原理
  6. 【clickhouse】ClickHouse 在实时场景的应用和优化-字节跳动技术沙龙第6期 笔记
  7. 上计算机课玩游戏检讨400字,上网课玩游戏检讨书
  8. 算法-无向图(深度优先搜索和广度优先搜索)
  9. 东西湖职业技术学校计算机专业怎么样,武汉东西湖职业技术学校怎么样
  10. linux设置ipsan_Linux下搭建iSCSI共享存储详细步骤(服务器模拟IPSAN存储)
  11. 奥斯汀页眉怎么设置_Word页眉横线怎么去掉与页眉页脚如何设置删除,含首页、奇数偶数页、横纵向页不同及第一页与最后一页不要页...
  12. css精华怎么使用,css橄榄精华好用吗?css橄榄精华评测
  13. Vue项目中实现改变屏幕尺寸重新刷新页面-计算页面尺寸
  14. 罗振宇“时间的朋友”跨年演讲:为做事的人服务 准确抓住小趋势
  15. 读书笔记:普通心理学之个体心理
  16. matlab 定时器timercallback,matlab定时器timer的用法,特别要注意回调函数的参数!...
  17. Polar码译码C语言程序,任意码长的Polar码编码方法与流程
  18. 16天记住英语7000个单词,300个句子
  19. 曾经最好用的浏览器凉了?正在被大批网站抛弃
  20. 使用python识别图像中的文字

热门文章

  1. 一步一步实现自己的模拟控件(9)——消息处理
  2. matlab生成多组多维高斯分布数据
  3. usaco ★Longest Prefix 最长前缀
  4. mysql数据库比对视频教程_MySQL数据库全学习实战视频教程(27讲 )
  5. 如何锁门_保安巡查时发现住户未锁门,应该怎么办?记住这九点!
  6. 74ls390设计任意进制计数器_异步FIFO:设计原理及Verliog源码
  7. python3操作mysql教程_python3操作mysql教程
  8. tcp拥塞控制编程实验c语言代码,C语言 计算机网络TCP拥塞控制模拟程序
  9. ndk 不用java_使用NDK创建及配置C++程序(原生纯C++项目,不包含JAVA代码)
  10. python图表交互控件_用djang中的交互式控件制作bokeh图表