https://www.luogu.org/problemnew/show/P4234

按照边的权值从小到大排序,依次加入,并删除能够删除的权值最小的一条边,用 set 维护当前所有边的边权,并查集维护联通性,LCT 维护两点间最小值和 link cut 操作即可

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;typedef unsigned long long ull;
typedef long long ll;template <typename _T>
inline void read(_T &f) {f = 0; _T fu = 1; char c = getchar();while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();}while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}f *= fu;
}const int N = 250000 + 10;struct ele {int u, v, a;bool operator < (const ele A) const {return a < A.a;}
}p[N];set < pair <int, int> > Min;
int fa[N], ch[N][2], rev[N], minn[N], val[N], wz[N], st[N], f[N], n, m, len, cnt, ans = INT_MAX;int isroot(int u) {return ch[fa[u]][0] != u && ch[fa[u]][1] != u;}
int get(int u) {return ch[fa[u]][1] == u;}void update(int u) {minn[u] = val[u]; wz[u] = u;if(minn[ch[u][0]] < minn[u] && ch[u][0]) minn[u] = minn[ch[u][0]], wz[u] = wz[ch[u][0]];if(minn[ch[u][1]] < minn[u] && ch[u][1]) minn[u] = minn[ch[u][1]], wz[u] = wz[ch[u][1]];
}void pushdown(int u) {if(rev[u]) {swap(ch[u][0], ch[u][1]);rev[ch[u][0]] ^= 1;rev[ch[u][1]] ^= 1;rev[u] ^= 1;}
}void rotate(int u) {int old = fa[u], oldd = fa[old], k = get(u);if(!isroot(old)) ch[oldd][get(old)] = u; fa[u] = oldd;ch[old][k] = ch[u][k ^ 1]; fa[ch[u][k ^ 1]] = old;fa[old] = u; ch[u][k ^ 1] = old;update(old); update(u);
}void splay(int u) {st[len = 1] = u;for(int i = u; !isroot(i); i = fa[i]) st[++len] = fa[i];for(int i = len; i >= 1; i--) pushdown(st[i]);for(; !isroot(u); rotate(u)) if(!isroot(fa[u])) rotate(get(u) == get(fa[u]) ? fa[u] : u);
}void access(int u) {for(int i = 0; u; i = u, u = fa[u]) {splay(u);ch[u][1] = i;update(u);}
}void makeroot(int u) {access(u);splay(u);rev[u] ^= 1;
}void link(int u, int v) {makeroot(u);fa[u] = v;
}void cut(int u, int v) {makeroot(u);access(v);splay(v);fa[u] = ch[v][0] = 0;update(v);
}int query(int u, int v) {makeroot(u);access(v);splay(v);return wz[v];
}int find(int x) {return f[x] == x ? x : f[x] = find(f[x]);}int main() {read(n); read(m);for(int i = 1; i <= n; i++) f[i] = i, val[i] = INT_MAX;for(int i = 1; i <= m; i++) {read(p[i].u);read(p[i].v);read(p[i].a);}sort(p + 1, p + m + 1);for(int i = 1; i <= m; i++) {int x = p[i].u, y = p[i].v;if(find(x) != find(y)) {cnt++; f[find(x)] = find(y);val[i + n] = p[i].a;link(i + n, x);link(i + n, y);Min.insert(mp(p[i].a, i)); } else {if(x == y) continue;int wz = query(x, y);val[i + n] = p[i].a;cut(wz, p[wz - n].u);cut(wz, p[wz - n].v);link(i + n, x);link(i + n, y);Min.erase(mp(p[wz - n].a, wz - n));Min.insert(mp(p[i].a, i));}if(cnt == n - 1) {set < pair <int, int> > :: iterator it = Min.begin();ans = min(ans, p[i].a - it -> first);}}cout << ans << endl;return 0;
}

转载于:https://www.cnblogs.com/LJC00118/p/9567210.html

luoguP4234 最小差值生成树相关推荐

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

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

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

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

  3. LeetCode简单题之学生分数的最小差值

    题目 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数.另给你一个整数 k . 从数组中选出任意 k 名学生的分数,使这 k 个分数间 最高分 和 最 ...

  4. mysql获取两个表中日期字段的最小差值

    一.前言 开发中碰到的需求,获取两个数据表中日期字段的差值,并且取得差值最小的那条数据.本篇文章主要讲述如果通过函数获取mysql的日期差值,实际编写时遇到的问题,并且分析需求,得出最终sql等. 二 ...

  5. 算法--06年华为面试:求两个数组的最小差值(Java实现)

    Q题目 华为06年面试题(要求8分钟完成) 有两个数组a,b,大小都为n,数组元素的值任意,无序: 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小. A解法 1.常见错误逻 ...

  6. 算法--微软面试题:求一个整数数组元素间最小差值

    Q题目 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数. A解法 方案一:最愚笨的办法--暴力穷举 利用数组中所有数据两两相减的对比来求出这个最小差值. ...

  7. 「 每日一练,快乐水题 」1984. 学生分数的最小差值

    ✅力扣原题: 力扣链接:1984. 学生分数的最小差值 ✅题目简述: 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数.另给你一个整数 k . 从数组 ...

  8. 1984. 学生分数的最小差值

    1984. 学生分数的最小差值 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数.另给你一个整数 k . 从数组中选出任意 k 名学生的分数,使这 k ...

  9. leetcode910. 最小差值 II(贪心)

    给定一个整数数组 A,对于每个整数 A[i],我们可以选择 x = -K 或是 x = K,并将 x 加到 A[i] 中. 在此过程之后,我们得到一些数组 B. 返回 B 的最大值和 B 的最小值之间 ...

  10. LeetCode 1984. 学生分数的最小差值

    文章目录 1. 题目 2. 解题 1. 题目 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数.另给你一个整数 k . 从数组中选出任意 k 名学生的 ...

最新文章

  1. html br/引起的”血案“
  2. android开发 BaseAdapter中getView()里的3个参数是什么意思
  3. ASP.NETserver控件使用之Reportviewer 报表
  4. javascript闭包,你大爷永远是你大爷
  5. 大数据和云计算涉及的技术_云计算涉及的风险
  6. 开源syslog服务器_开源API网关Kong基本介绍和安装验证
  7. 【推荐系统】16篇最新推荐系统论文送你
  8. nbiot和2g_nb-iot和4G谁才是物联网未来的趋势?不同行业应该如何选择?
  9. 学考计算机会考考点工作总结,高中生学业水平考试工作总结范文
  10. windows8.1 下搭建配置apache+php+mysql
  11. php 运行c语言,echo c语言运行
  12. Java实战项目之人力资源管理系统【源码+课后指导】_Java毕业设计/计算机毕业设计
  13. 免费python课程-Python零基础免费入门课程
  14. c盘文件被木马删怎么恢复?教你四步轻松找回文件!
  15. 客户细分那点事_理论篇
  16. 数据库数据更新(insert、update、delete)
  17. Windows 安装包介绍
  18. Python人体肤色检测
  19. SIGIR‘22 推荐系统论文之POI篇
  20. 2.文件系统及相关命令

热门文章

  1. 火影手游服务器维护多久,《火影忍者》手游结束终极内测的停服公告
  2. java中解耦合_简单分析程序中耦合和解耦合
  3. SAT数学公式之几何图形
  4. python获取北京时间_python获取标准北京时间的方法
  5. Halcon区域形状特征-area_center、area_holes、select_shape、inner_circle和smallest_rectangle2算子
  6. html5课程总结500字,月考总结500字作文5篇
  7. Python collections.Counter()用法
  8. Python库collections中的计数器(Counter)
  9. linux限制进程带宽,再Linux系统中限制网络带宽使用的教程
  10. wuauclt1.exe mshta.exe 病毒清理