[Luogu] 最小差值生成树
https://www.luogu.org/recordnew/show/6125570
思路就是巧妙的枚举所有的生成树,取最优值
首先按照边权排序
找出第一颗最小生成树(l, r),其中l表示最小边的编号,r表示最大边的编号
然后从r+1号边开始倒序枚举各边,求出第二颗最小生成树(当然也可能不存在)(l_2, r_2), r_2 = r + 1.
这样的话就省去了多条最小边的枚举
比如若从2 -- l_2-1中任选一条边作为最小边开始查询最大生成树,那么最大边一定为r_2
这样的话差值不会比(l_2, r_2)这颗生成树更优,所以就简化了算法
然后从将l_2+1号边作为最小边开始枚举,依次进行下去
#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std;
const int N = 5e4 + ; #define gc getchar() int fa[N];
struct Node{int u, v, w;} G[N << ];
int n, m, Answer = ; inline int read() {
int x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} inline bool cmp(Node a, Node b) {return a.w < b.w;}
int get_fa(int x) {return fa[x] == x ? x : fa[x] = get_fa(fa[x]);}
void Printf() {cout << Answer; exit();} void dfs(int start, int how) {
for(int i = ; i <= n; i ++) fa[i] = i;
int tot = , Maxn = , Minn = , Nxt;
if(how % ) {//cong xiao dao da
for(int i = start; i <= m; i ++) {
int fa_u = get_fa(G[i].u), fa_v = get_fa(G[i].v);
if(fa_u != fa_v) {
fa[fa_u] = fa_v;
tot ++;
if(tot == n - ) {Maxn = G[i].w; Nxt = i; break;}
}
}
if(!Maxn) Printf();
Answer = min(Answer, Maxn - G[start].w);
} else {
for(int i = start; i >= ; i --) {
int fa_u = get_fa(G[i].u), fa_v = get_fa(G[i].v);
if(fa_u != fa_v) {
fa[fa_u] = fa_v;
tot ++;
if(tot == n - ) {Minn = G[i].w; Nxt = i; break;
}
}
}
if(!Minn) Printf();
Answer = min(Answer, G[start].w - Minn);
}
dfs(Nxt + , how + );
} int main() {
n = read();
m = read();
for(int i = ; i <= m; i ++) G[i].u = read(), G[i].v = read(), G[i].w = read();
sort(G + , G + m + , cmp);
dfs(, );
return ;
}
[Luogu] 最小差值生成树的更多相关文章
- [luogu4234]最小差值生成树
[luogu4234]最小差值生成树 luogu 从小到大枚举边,并连接,如果已连通就删掉路径上最小边 lct维护 \(ans=min(E_{max}-E_{min})\) #include<b ...
- LuoguP4234_最小差值生成树_LCT
LuoguP4234_最小差值生成树_LCT 题意: 给出一个无向图,求最大的边权减最小的边权最小的一棵生成树. 分析: 可以把边权从大到小排序,然后类似魔法森林那样插入. 如果两点不连通,直接连上, ...
- P4234 最小差值生成树
题目 P4234 最小差值生成树 做法 和这题解法差不多,稍微变了一点,还不懂就直接看代码吧 \(update(2019.2):\)还是具体说一下吧,排序,直接加入,到了成环情况下,显然我们要把此边代 ...
- 【Luogu】P4234最小差值生成树(LCT)
题目链接 能把LCT打得每个函数都恰有一个错误也是挺令我惊讶的. 本题使用LCT维护生成树,具体做法是对原图中的每个边建一个点,然后连边的时候相当于是将边的起点跟“边”这个点连起来,边的终点也跟它连起 ...
- Luogu P4234 最小差值生成树
题意 给定一个 \(n\) 个点 \(m\) 条边的有权无向图,求出原图的一棵生成树使得该树上最大边权与最小边权的差值最小. \(\texttt{Data Range:}1\leq n\leq 5\t ...
- Luogu 4234 最小差值生成树 - LCT 维护链信息
Solution 将边从小到大排序, 添新边$(u, v)$时 若$u,v$不连通则直接添, 若连通则 把链上最小的边去掉 再添边. 若已经加入了 $N - 1$条边则更新答案. Code #incl ...
- luogu 4234 最小差值生成树 LCT
感觉码力严重下降~ #include <bits/stdc++.h> #define N 400006 #define inf 1000000000 #define setIO(s) fr ...
- POJ 3522 Slim Span 最小差值生成树
Slim Span Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=3522 Description Gi ...
- 洛谷.4234.最小差值生成树(LCT)
题目链接 先将边排序,这样就可以按从小到大的顺序维护生成树,枚举到一条未连通的边就连上,已连通则(用当前更大的)替换掉路径上最小的边,这样一定不会更差. 每次构成树时更新答案.答案就是当前边减去生成树 ...
随机推荐
- go struct 的方法1
方法 Go 没有类.然而,仍然可以在结构体类型上定义方法. 方法接收者 出现在 func 关键字和方法名之间的参数中. package main import ( "fmt" ...
- SAS学习笔记17 SAS生成随机数函数(rand function)
- 定义别名:typedef和using
定义别名:
- MySQL 触发器的使用
MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ...
- 怎样理解new命令的执行过程
通过new命令生成一个实例对象经历了四个步骤: 1. 创建一个空对象, 作为将要返回的实例; 2. 将空对象的原型指向构造函数的prototype属性; 3. 将空对象赋值给构造函数的this; 4. ...
- Angular 惰性路由
根路由上的一个 loadChildren 属性,设置为一个字符串.这样就是惰性路由了. angular6 这样写:loadChildren: './background-check/backgroun ...
- XML-RPC-1概述
XML-RPC是一个远程过程调用(远端程序呼叫)(remote procedure call,RPC)的分布式计算协议,通过XML将调用函数封装,并使用HTTP协议作为传送机制. 中文名 XML- ...
- 【原创】大叔经验分享(89)docker启动openjdk执行jmap报错
docker启动openjdk后,可以查看进程 # docker exec -it XXX jps 10 XXX.jar 可见启动的java进程id一直为10,然后可以执行jvm命令,比如 # doc ...
- 安全开发流程(SDL)学习概述
1.简介 SDL的全称是Security Development Lifecycle,即:安全开发生命周期.由微软最早提出,是一种专注于软件开发的安全保障流程.为实现保护最终用户为目标,它在软件开发流 ...
- Java之IO学习
知其然也要知其所以然,最近对IO流莫名的感觉时候充充电了,所以上网拜读了大神的文章.在学习过程中我找到了一篇很系统很详细的文章贴出来. 声明一下这是转载的文章 原文:https://www.cnbl ...