题目大意:给出一个n个节点的图,求最大边权值减去最小边权值最小的生成树。

题解

Flash Hu大佬一如既往地强

先把边从小到大排序

然后依次加入每一条边

如果已经连通就把路径上权值最小的边删去

然后记得更新答案

ps:不是很明白为啥我洛谷上吸了氧还跑得更慢了233

 //minamoto
#include<cstdio>
#include<algorithm>
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=,K=N+M;
struct edge{
int u,v,e;
inline bool operator <(const edge &b)const
{return e<b.e;}
}e[M];
int fa[K],ch[K][],s[K],mn[K],rev[K],top,v[K],vis[M],f[N];
int ff(int x){return f[x]==x?x:f[x]=ff(f[x]);}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline int get(int x,int y){return v[x]<v[y]?x:y;}
inline void pushup(int x){mn[x]=get(x,get(mn[ch[x][]],mn[ch[x][]]));}
inline void pushdown(int x){
if(x&&rev[x]){
swap(ch[x][],ch[x][]);
rev[ch[x][]]^=,rev[ch[x][]]^=;
rev[x]=;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void splay(int x){
s[top=]=x;for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i];
while(top) pushdown(s[top--]);
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x])
splay(x),ch[x][]=y,pushup(x);
}
inline void makeroot(int x){
access(x),splay(x),rev[x]^=;
}
inline void link(int x){
makeroot(e[x].u);
fa[fa[e[x].u]=N+x]=e[x].v;
}
inline void cut(int x){
access(e[x-N].u),splay(x);
ch[x][]=ch[x][]=fa[ch[x][]]=fa[ch[x][]]=;
/*因为link的时候把u的父亲设为边,所以u的深度最低
把它到根节点的路径打通就好了*/
}
int main(){
//freopen("testdata.in","r",stdin);
int n=read(),m=read();
int ans=;
for(int i=;i<=n;++i) f[i]=i,v[i]=inf;
for(int i=;i<=m;++i){
int u=read(),v=read(),k=read();
e[i]=(edge){u,v,k};
}
sort(e+,e++m);
for(int cnt=,h=,i=;i<=m;++i){
v[i+N]=e[i].e;
int u,v;
if(ff(u=e[i].u)!=ff(v=e[i].v)){
vis[i]=,link(i),f[f[u]]=f[v],++cnt;
if(cnt==n) ans=e[i].e-e[h].e;
}
else{
if(u==v) continue;
vis[i]=;
makeroot(u),access(v),splay(v);
vis[mn[v]-N]=;while(!vis[h]) ++h;
cut(mn[v]),link(i);
if(cnt==n) cmin(ans,e[i].e-e[h].e);
}
}
printf("%d\n",ans);
return ;
}

POJ 3522 最小差值生成树(LCT)的更多相关文章

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

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

  2. P4234 最小差值生成树 LCT维护边权

    \(\color{#0066ff}{ 题目描述 }\) 给定一个标号为从 \(1\) 到 \(n\) 的.有 \(m\) 条边的无向图,求边权最大值与最小值的差值最小的生成树. \(\color{#0 ...

  3. Luogu 4234 最小差值生成树 - LCT 维护链信息

    Solution 将边从小到大排序, 添新边$(u, v)$时 若$u,v$不连通则直接添, 若连通则 把链上最小的边去掉 再添边. 若已经加入了 $N - 1$条边则更新答案. Code #incl ...

  4. 洛谷 P4234 最小差值生成树(LCT)

    题面 luogu 题解 LCT 动态树Link-cut tree(LCT)总结 考虑先按边权排序,从小到大加边 如果构成一颗树了,就更新答案 当加入一条边,会形成环. 贪心地想,我们要最大边权-最小边 ...

  5. luogu 4234 最小差值生成树 LCT

    感觉码力严重下降~ #include <bits/stdc++.h> #define N 400006 #define inf 1000000000 #define setIO(s) fr ...

  6. LuoguP4234_最小差值生成树_LCT

    LuoguP4234_最小差值生成树_LCT 题意: 给出一个无向图,求最大的边权减最小的边权最小的一棵生成树. 分析: 可以把边权从大到小排序,然后类似魔法森林那样插入. 如果两点不连通,直接连上, ...

  7. [luogu4234]最小差值生成树

    [luogu4234]最小差值生成树 luogu 从小到大枚举边,并连接,如果已连通就删掉路径上最小边 lct维护 \(ans=min(E_{max}-E_{min})\) #include<b ...

  8. P4234 最小差值生成树

    题目 P4234 最小差值生成树 做法 和这题解法差不多,稍微变了一点,还不懂就直接看代码吧 \(update(2019.2):\)还是具体说一下吧,排序,直接加入,到了成环情况下,显然我们要把此边代 ...

  9. POJ 3522 Slim Span 最小差值生成树

    Slim Span Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=3522 Description Gi ...

随机推荐

  1. hdu3999-The order of a Tree (二叉树的先序遍历)

    http://acm.hdu.edu.cn/showproblem.php?pid=3999 The order of a Tree Time Limit: 2000/1000 MS (Java/Ot ...

  2. 搭建yum本地源_阿里云CentOS服务器初始化设置

    CentOS服务器初始化设置其实不分阿里云或其它服务器了,操作配置过程与步骤也差不多一.挂载硬盘 1.磁盘分区 fdisk -l #查看设备,一般可以看到设备名为/dev/xvdb fdisk /de ...

  3. 410. Split Array Largest Sum 把数组划分为m组,怎样使最大和最小

    [抄题]: Given an array which consists of non-negative integers and an integer m, you can split the arr ...

  4. 第一话:IE中用DOM方法绑定事件

    工作比较忙,但是也一定要抽时间出来提升一下自己的基本功,只有技术实力到位,才能为公司和个人创造更多的价值.下面进入主题: IE中事件监听比较容易用到,但是由它所引出的一个关于this的问题,不得不着重 ...

  5. XSS的原理分析与解剖(第二篇)[转]

    0×01 前言: 上节(http://www.freebuf.com/articles/web/40520.html)已经说明了xss的原理及不同环境的构造方法.本期来说说XSS的分类及挖掘方法. 当 ...

  6. 运行jupyter

    在mac 命令行中输入 jupyter notebook 即可 https://www.datacamp.com/community/tutorials/tutorial-jupyter-notebo ...

  7. es-多文档简单查询(_mget)

    1.多文档查询 (1)url:POST http://localhost:9200/_mget?pretty/ 参数: { "docs": [{ "_index" ...

  8. .NET分布式事务处理(转)

    出处:http://www.cnblogs.com/youring2/archive/2011/06/12/MSDTC.html 在进行数据持久化的时候,我们会经常用到事务处理.一般情况下,ADO.N ...

  9. C/C++语言中指针数组和数组指针比较区别

    指针数组:int *p[3] 定义一个指针数组,其中每个数组元素指向一个int型变量的地址 意思就是指针的数组,数组里面都是指针 例子: int *p[3];//定义了一个指针数组,有3个成员,每个成 ...

  10. Ajax之XMLHttpRequest

    XMLHttpRequest对象 XMLHttpRequest  提供客户端同http服务器通讯的协议 一:创建 IE : http_request = new ActiveXObject(" ...