洛谷 p4234 最小差值生成树

news/2024/11/21 1:46:47/

    • 题意
    • 题解

题意

求最长边与最短边差值最小的生成树.

题解

LCT裸题.
将边按照边权从小到大排序,产生生成树的同时立即更新答案.
如果加入一条边的时候出现了环,把环上最小的边去掉加入该边.
每次跑最小值即可,用LCT可以较方便地维护.
为什么RE了啊啊啊啊啊啊啊啊啊!!!!!!!!!!!!!!!

#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){int x=0,f=1;char c=gc();for (;!isdigit(c);c=gc()) f^=c=='-';for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');return f?x:-x;}
template <typename mitsuha>
inline bool read(mitsuha &x){x=0;int f=1;char c=gc();for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';if (!~c) return 0;for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');return x=f?x:-x,1;}
template <typename mitsuha>
inline int write(mitsuha x){if (!x) return 0&pc(48);if (x<0) x=-x,pc('-');int bit[20],i,p=0;for (;x;x/=10) bit[++p]=x%10;for (i=p;i;--i) pc(bit[i]+48);return 0;}
inline char fuhao(){char c=gc();for (;isspace(c);c=gc());return c;}
}using namespace chtholly;
using namespace std;
const int yuzu=4e5,inf=0x3f3f3f3f;
typedef int fuko[yuzu|10];
fuko vis;
struct edge{
int u,v,w;
void rd(){u=read(),v=read(),w=read();}
void wt(){printf("%d %d %d\n",u,v,w);}
bool operator <(const edge &b) const{return w<b.w;}
}e[yuzu|10];struct link_cut_tree{
fuko fa,ch[2],val,tag,xiao;
#define ls(x) ch[0][x]
#define rs(x) ch[1][x]
#define ws(x,y) (rs(x)==y)
int nrt(int x){return ls(fa[x])==x||rs(fa[x])==x;}
void rev(int x){swap(ls(x),rs(x)),tag[x]^=1;}
void push_down(int x){if (tag[x]) rev(ls(x)),rev(rs(x)),tag[x]=0;} 
void pushall(int x){if (nrt(x)) pushall(fa[x]); push_down(x);} 
void push_up(int x){xiao[x]=val[x];if (e[xiao[ls(x)]].w<e[xiao[x]].w) xiao[x]=xiao[ls(x)];if (e[xiao[rs(x)]].w<e[xiao[x]].w) xiao[x]=xiao[rs(x)];}
void zhuan(int x){int y=fa[x],z=fa[y],k=ws(y,x),ps=ch[!k][x];if (nrt(y)) ch[ws(z,y)][z]=x;ch[k][y]=ps,ch[!k][x]=y;if (ps) fa[ps]=y;fa[x]=z,fa[y]=x,push_up(y);}
void splay(int x){pushall(x);for (;nrt(x);zhuan(x)){int y=fa[x],z=fa[y];if (nrt(y)) zhuan(ws(z,y)^ws(y,x)?x:y);}push_up(x);}
void access(int x){for (int y=0;x;y=x,x=fa[x]) splay(x),rs(x)=y,push_up(x);}
void mkrt(int x){access(x),splay(x),rev(x);}
void split(int x,int y){mkrt(x),access(y),splay(y);}
int fdrt(int x){access(x),splay(x);for (;ls(x);x=ls(x)) push_down(x);return x;}
int link(int x,int y){mkrt(x),fa[x]=y;}
int cut(int x,int y){split(x,y),fa[x]=ls(y)=0,push_up(y);}
}my_;
#define val my_.val
#define xiao my_.xiao
#define access my_.access
#define split my_.split
#define mkrt my_.mkrt
#define splay my_.splay
#define link my_.link
#define cut my_.cut
#define fdrt my_.fdrt
int main(){
int i,n=read(),m=read(),llx=inf;
for (i=1;i<=m;++i) e[i].rd();
e[0].w=inf,sort(e+1,e+m+1);
int cnt=0,k=1;
for (i=0;i<=n+m;++i) val[i]=i<=n?0:i-n;
for (i=1;i<=m;++i){int u=e[i].u,v=e[i].v,w=e[i].w;if (u^v){if (fdrt(u)==fdrt(v)){split(u,v);int id=xiao[v];vis[id]=0;cut(e[id].u,id+n),cut(id+n,e[id].v),--cnt;} link(u,i+n),link(i+n,v),++cnt;vis[i]=1;}if (cnt>=n-1){for (;!vis[k];++k);llx=min(llx,w-e[k].w);} }
write(llx);
}

谢谢大家.


http://www.ppmy.cn/news/356266.html

相关文章

【洛谷P4234】最小差值生成树

Description 给定一张n个点&#xff0c;m条边的无向图&#xff0c;求出边权最大值和最小值差值最小的生成树 Solution LCT并查集 按照最小生成树的思路&#xff0c;先将边按照边权从小到大排序&#xff0c;然后顺序考虑每一条边 如果当前这条边的两个端点没有连通&#xff0c;那…

luogu 4234 最小差值生成树 LCT

感觉码力严重下降~ #include <bits/stdc.h> #define N 400006 #define inf 1000000000 #define setIO(s) freopen(s".in","r",stdin) using namespace std; multiset<int>S; multiset<int>::iterator it; struct…

洛谷P4234 最小差值生成树

LCT维护生成树 把边从小到大排序&#xff0c;然后一条一条加边&#xff0c;如果成环就把环上最小的删了&#xff0c;我们得到的第一个生成树就是最小生成树。 然后之后每一条边都比前面的生成树的最大边大&#xff0c;我们用这条边的权值减去生成树里最小的&#xff0c;更新答案…

洛谷 P4234 LCT + 排序 + 枚举

求边权最大值与最小值的差值最小的生成树&#xff0c;输出这个差值大小。 按权值排序&#xff0c;我们等同于枚举最大值&#xff0c;然后更新生成树让生成树的最小值尽可能最大。 也就是每次加入边&#xff0c;若构成环&#xff0c;则去掉环上最小值。 若加入边不会构成环&…

LuoguP4234_最小差值生成树_LCT

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

NKOJ 4234 三角分形

问题描述 今天何老板得到了一个神奇的正三角形&#xff0c;它具有自动分形技能。 一天后&#xff0c;它会分成4个相同的正三角形&#xff0c;其中三个“尖尖”朝上&#xff0c;一个“尖尖”朝下。 一天后&#xff0c;里面的每个三角形又会按上述规则分形下去。 如此反复………

[luogu4234]最小差值生成树

[luogu4234]最小差值生成树 luogu 从小到大枚举边,并连接,如果已连通就删掉路径上最小边 lct维护\(ansmin(E_{max}-E_{min})\) #include<bits/stdc.h> using namespace std; const int _4e55; int re(){int x0,w1;char chgetchar();while(ch<0||ch>9){if(ch-)w-1;c…

HDU 4234 Moving Points

刚开始做的时候还以为是暴搜&#xff0c;YY了各种剪枝&#xff0c;结果华丽丽的TLE了 正解&#xff1a; 状态压缩DP dp[当前走到的点][状态] 状态&#xff1a; 第i位表示第i个点有没有被消灭 转移&#xff1a; 详见代码 注意&#xff1a; 计算转移cost时要用O(1) 的算法 二分…