题目大意:给出一个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. Unity Remote 5 使用

    从哪里下载,我是从应用商店里下载的 一. Android版 首先应该确保安装了最新的 Android SDK(这对于在设备上设置端口转发非常必要). 然后,使用 USB 连接线连接设备与电脑,并启动U ...

  2. HTML5新增的非主体结构元素

    -------------------siwuxie095                                 HTML5 新增的非主体结构元素         1.header 元素   ...

  3. tomcat安装后,双击start.bat闪退的问题

    1.jdk环境变量没有配 解决方案:我的电脑-属性-高级-环境变量,新增下面三个环境变量: ①JAVA_HOME=C:\Program Files\Java\jdk1.7.0_09(就是你jdk安装的 ...

  4. Weblogic10.3.6部署解决CXF webService 调用报错: “Cannot create a secure XMLInputFactory”

    一,解决步骤 1.添加jar包 stax2-api-3.1.4.jar woodstox-core-asl-4.4.1.jar 2.编写监听器 package com.neusoft.cxf.list ...

  5. appium_server_v1.4.16版本不适配android7.0系统,运行报错“Attempt to re-install io.appium.settings without first uninstalling”

    要解决的问题:appium在androidV7.0系统上运行时报错 Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install io.a ...

  6. Use formatter to format your JAVA code

    In order to make the codes looks unified and make it easy to understand, it's better to use the same ...

  7. 安装CentOS 6.4 64 位操作系统

    1.安装 CentOS 6.4 64位操作系统的一些困境: 1.1 CentOS 6.4 64位操作系统的ISO文件有4G多,通过U盘安装的方式已经不可取(FAT32 只支持最大4G文件); 1.2 ...

  8. es学习-基础增删改查

    创建库 插入数据 修改文档: 查询文档: 删除文档:

  9. (转)走进AngularJs(六) 服务

    原文地址:http://www.cnblogs.com/lvdabao/p/3464015.html 今天学习了一下ng的service机制,作为ng的基本知识之一,有必要做一个了解,在此做个笔记记录 ...

  10. 如何Android中加入扫描名片功能

    要想实现android手机通过扫描名片,得到名片信息,可以使用脉可寻提供的第三方SDK,即Maketion ScanCard SDK,脉可寻云名片识别服务.他们的官方网站为http://www.mak ...