「CF827D Best Edge Weight」 - LCT
Posted xay5421
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「CF827D Best Edge Weight」 - LCT相关的知识,希望对你有一定的参考价值。
CF827D Best Edge Weight
tags:LCT
题意
给你一张有边权的简单图,现在要求对于每一条边求出,这条边的边权最大为多少时,它还能出现在所有可能的最小生成树上,如果对于任意边权都出现,则输出 -1
题解
分类讨论
- 这条边在最小生成树上,那么就是所有可以取代这条边的非树边的最小值-1
- 这个边不在最小生成树上,那么就是这条边可以取代的树边是最小值-1
直接 LCT 维护即可,时间复杂度 \(O(n\log n)\)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
template<typename T>void rd(T&x)int f=0,c;while((c=getchar())<48||57<c)f^=!(c^45);x=(c&15);while(47<(c=getchar())&&c<58)x=x*10+(c&15);if(f)x=-x;
template<typename T>T max(const T&x,const T&y)return x<y?y:x;
template<typename T>T min(const T&x,const T&y)return x<y?x:y;
const int N=400005,INF=0x3f3f3f3f;
int n,m,ans[N],st[N],val[N],fa[N],rev[N],tag[N],mx[N],ch[N][2];bool vis[N];
struct edgeint u,v,w,id;bool operator<(const edge&b)constreturn w<b.w;e[N];
int get(int u)return ch[fa[u]][1]==u;
int isroot(int u)return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
void update(int u)mx[u]=max(val[u],max(mx[ch[u][0]],mx[ch[u][1]]));
void puttag(int u,int w)ans[u]=min(ans[u],w),tag[u]=min(tag[u],w);
void pushdown(int u)
if(rev[u])std::swap(ch[u][0],ch[u][1]),rev[ch[u][0]]^=1,rev[ch[u][1]]^=1,rev[u]^=1;
if(tag[u]!=INF)puttag(ch[u][0],tag[u]),puttag(ch[u][1],tag[u]),tag[u]=INF;
void rotate(int u)
int p=fa[u],gp=fa[p],x=get(u);
if(!isroot(p))ch[gp][get(p)]=u;fa[u]=gp;
ch[p][x]=ch[u][x^1],fa[ch[u][x^1]]=p;
ch[u][x^1]=p,fa[p]=u;
update(p),update(u);
void splay(int u)
st[*st=1]=u;
for(int i=u;!isroot(i);i=fa[i])st[++*st]=fa[i];
for(int i=*st;i>=1;--i)pushdown(st[i]);
for(;!isroot(u);rotate(u))
if(!isroot(fa[u]))
rotate(get(u)==get(fa[u])?fa[u]:u);
void access(int u)
for(int i=0;u;i=u,u=fa[u])
splay(u);
ch[u][1]=i;
update(u);
void makeroot(int u)
access(u);
splay(u),rev[u]^=1;
void link(int u,int v)
makeroot(u),fa[u]=v;
int findroot(int u)
access(u),splay(u);
while(ch[u][0])u=ch[u][0];
return u;
int main()
memset(ans,63,sizeof(ans)),memset(tag,63,sizeof(tag));
rd(n),rd(m);rep(i,1,m)rd(e[i].u),rd(e[i].v),rd(e[i].w),e[i].id=i;std::sort(e+1,e+1+m);
rep(i,1,m)
int u=e[i].u,v=e[i].v,w=e[i].w,id=e[i].id+n;
if(findroot(u)!=findroot(v))
val[id]=w;
link(u,id);
link(v,id);
vis[id]=1;
else
makeroot(u),access(v),splay(v);
ans[id]=mx[v]-1;
puttag(v,w);
rep(i,n+1,n+m)
if(vis[i])
access(i),splay(i);
if(ans[i]!=INF)printf("%d ",ans[i]-1);else printf("%d ",-1);
else printf("%d ",ans[i]);
return 0;
以上是关于「CF827D Best Edge Weight」 - LCT的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 827D Best Edge Weight 倍增 + 并查集 || 倍增 + 压倍增标记 (看题解)
Codeforces827D. Best Edge Weight
CodeForces827 D. Best Edge Weight 最小生成树+倍增LCA+并查集