P4234-最小差值生成树【LCT】
正题
题目链接: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
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int N=3e5+10;
struct node{
int x,y,w;
}e[N];
int n,m,p[N],fa[N];bool v[N];
struct LCT{
int fa[N],t[N][2];
bool r[N];stack<int> s;
bool Nroot(int x)
{return fa[x]&&(t[fa[x]][0]==x||t[fa[x]][1]==x);}
bool Direct(int x)
{return t[fa[x]][1]==x;}
void PushUp(int x)
{p[x]=min(min(p[t[x][0]],p[t[x][1]]),x);return;}
void Rev(int x)
{r[x]^=1;swap(t[x][0],t[x][1]);return;}
void PushDown(int x)
{if(r[x])Rev(t[x][0]),Rev(t[x][1]),r[x]=0;return;}
void Rotate(int x){
int y=fa[x],z=fa[y];
int xs=Direct(x),ys=Direct(y);
int w=t[x][xs^1];
t[y][xs]=w;t[x][xs^1]=y;
if(Nroot(y))t[z][ys]=x;
if(w)fa[w]=y;fa[y]=x;fa[x]=z;
PushUp(y);PushUp(x);return;
}
void Splay(int x){
int y=x;s.push(x);
while(Nroot(y))y=fa[y],s.push(y);
while(!s.empty())PushDown(s.top()),s.pop();
while(Nroot(x)){
int y=fa[x];
if(!Nroot(y))Rotate(x);
else if(Direct(x)==Direct(y))
Rotate(y),Rotate(x);
else Rotate(x),Rotate(x);
}
return;
}
void Access(int x){
for(int y=0;x;y=x,x=fa[x])
Splay(x),t[x][1]=y,PushUp(x);
return;
}
void MakeRoot(int x)
{Access(x);Splay(x);Rev(x);return;}
int Split(int x,int y)
{MakeRoot(x);Access(y);Splay(y);return p[y];}
void Link(int x,int y)
{MakeRoot(x);fa[x]=y;Access(x);return;}
void Cut(int x,int y)
{MakeRoot(x);Access(y);Splay(y);fa[t[y][0]]=0;t[y][0]=0;PushUp(y);return;}
}T;
int find(int x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
bool cmp(node x,node y)
{return x.w<y.w;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
sort(e+1,e+1+m,cmp);
memset(p,0x3f,sizeof(p));
for(int i=1;i<=n+m;i++)fa[i]=p[i]=i;
int k=n,z=0,ans=1e5;
for(int i=1;i<=m;i++){
int x=e[i].x,y=e[i].y;
if(x==y)continue;
int fx=find(x),fy=find(y);
if(fx==fy){
int num=T.Split(x+m,y+m);
T.Cut(e[num].x+m,num);
T.Cut(num,e[num].y+m);
v[num]=0;
}
else fa[fx]=fy,k--;
T.Link(x+m,i);T.Link(i,y+m);
v[i]=1;while(!v[z])z++;
if(k==1)ans=min(ans,e[i].w-e[z].w);
}
printf("%d\n",ans);
return 0;
}
P4234-最小差值生成树【LCT】的更多相关文章
- P4234 最小差值生成树 LCT维护边权
\(\color{#0066ff}{ 题目描述 }\) 给定一个标号为从 \(1\) 到 \(n\) 的.有 \(m\) 条边的无向图,求边权最大值与最小值的差值最小的生成树. \(\color{#0 ...
- 洛谷 P4234 最小差值生成树(LCT)
题面 luogu 题解 LCT 动态树Link-cut tree(LCT)总结 考虑先按边权排序,从小到大加边 如果构成一颗树了,就更新答案 当加入一条边,会形成环. 贪心地想,我们要最大边权-最小边 ...
- P4234 最小差值生成树
题目 P4234 最小差值生成树 做法 和这题解法差不多,稍微变了一点,还不懂就直接看代码吧 \(update(2019.2):\)还是具体说一下吧,排序,直接加入,到了成环情况下,显然我们要把此边代 ...
- 洛谷.4234.最小差值生成树(LCT)
题目链接 先将边排序,这样就可以按从小到大的顺序维护生成树,枚举到一条未连通的边就连上,已连通则(用当前更大的)替换掉路径上最小的边,这样一定不会更差. 每次构成树时更新答案.答案就是当前边减去生成树 ...
- 洛谷P4234 最小差值生成树(lct动态维护最小生成树)
题目描述 给定一个标号为从 11 到 nn 的.有 mm 条边的无向图,求边权最大值与最小值的差值最小的生成树. 输入输出格式 输入格式: 第一行两个数 n, mn,m ,表示图的点和边的数量. ...
- 【Luogu】P4234最小差值生成树(LCT)
题目链接 能把LCT打得每个函数都恰有一个错误也是挺令我惊讶的. 本题使用LCT维护生成树,具体做法是对原图中的每个边建一个点,然后连边的时候相当于是将边的起点跟“边”这个点连起来,边的终点也跟它连起 ...
- 洛谷P4234 最小差值生成树(LCT,生成树)
洛谷题目传送门 和魔法森林有点像,都是动态维护最小生成树(可参考一下Blog的LCT总结相关部分) 至于从小到大还是从大到小当然无所谓啦,我是从小到大排序,每次枚举边,还没连通就连,已连通就替换环上最 ...
- 【刷题】洛谷 P4234 最小差值生成树
题目描述 给定一个标号为从 \(1\) 到 \(n\) 的.有 \(m\) 条边的无向图,求边权最大值与最小值的差值最小的生成树. 输入输出格式 输入格式: 第一行两个数 \(n, m\) ,表示图的 ...
- Luogu P4234 最小差值生成树
题意 给定一个 \(n\) 个点 \(m\) 条边的有权无向图,求出原图的一棵生成树使得该树上最大边权与最小边权的差值最小. \(\texttt{Data Range:}1\leq n\leq 5\t ...
- [洛谷P4234] 最小差值生成树
题目类型:\(LCT\)动态维护最小生成树 传送门:>Here< 题意:求一棵生成树,其最大边权减最小边权最小 解题思路 和魔法森林非常像.先对所有边进行排序,每次加边的时候删除环上的最小 ...
随机推荐
- ubunt中,使用命令su命令切换root账户,提示认证失败
报错截图: 解决方法: sudo passwd 重新设置root账户的密码,确认root账户的密码(再次输入密码),然后su ,输入root账户刚刚设置的密码即可切入到root账户:
- tcphdr结构
包含在/usr/src/linux/include/linux/tcp.h 1 struct tcphdr { 2 __be16 source; 3 __be16 dest; 4 __be32 seq ...
- ArcGIS:从DEM数据提取对应点的高程
通过Extract Value to Points从DEM数据中提取所需点的高程. 方法/步骤 将DEM数据文件和一个shapefile点文件(分别命名为"DEM"和"P ...
- java基本数据类型转换字符串
1.基本数据类型转换为字符串 int t1 = 2; String t2 = Integer.toString(t1); 2.字符串转换为基本数据类型 int t3 = Integer.parseIn ...
- save tran tranName
begin tran 语句将 @@Trancount加 1.Rollback tran将 @@Trancount递减到 0,但 Rollback tran savepoint_name 除外,它不影响 ...
- Linux命令集锦之·字符截取命令
时间:2018-11-15 记录:byzqy 字符截取命令: cut.printf.awk.sed cut $ cut [选项] 文件名 选项: -f 列号:提取第几列: -d 分隔符:按照指定分隔符 ...
- Shell中常用的语句
exit 完全中断脚本的执行 break 中断脚本的循环,但是会执行循环外的语句 continue 跳出本次循环,进行下一次循环 进一步了解三者的区别,有如下实验: 执行该脚本: 脚本正常运行情况: ...
- vue 前端反向代理后台,解决跨域问题
// 和 src 同层的 config 文件夹下的 index.js dev 里面的 // Paths assetsSubDirectory: 'static', assetsPubl ...
- IDEA中mybatis generator使用
1.在对应服务的pom.xml文件中添加依赖 <build> <plugins> <plugin> <groupId>org.mybatis.gener ...
- java 线程基础篇,看这一篇就够了。
前言: Java三大基础框架:集合,线程,io基本是开发必用,面试必问的核心内容,今天我们讲讲线程. 想要把线程理解透彻,这需要具备很多方面的知识和经验,本篇主要是关于线程基础包括线程状态和常用方法. ...