luogu 4234 最小差值生成树 LCT
Posted guangheli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 Edge int u,v,c; Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c) e[N]; bool cmp(Edge a,Edge b) return a.c<b.c; struct Union int p[N]; void init() for(int i=1;i<N;++i) p[i]=i; int find(int x) return p[x]==x?x:p[x]=find(p[x]); int merge(int x,int y) x=find(x),y=find(y); if(x!=y) p[x]=y; return 1; return 0; ufs; struct Link_Cut_Tree #define lson t[x].ch[0] #define rson t[x].ch[1] int sta[N]; struct Node int ch[2],f,min,id,val,rev; t[N]; int isrt(int x) return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x); int get(int x) return t[t[x].f].ch[1]==x; void pushup(int x) t[x].min=t[x].val, t[x].id=x; if(lson && t[lson].min<t[x].min) t[x].min=t[lson].min,t[x].id=t[lson].id; if(rson && t[rson].min<t[x].min) t[x].min=t[rson].min,t[x].id=t[rson].id; void mark(int x) if(x) t[x].rev^=1,swap(lson,rson); void pushdown(int x) if(t[x].rev) if(lson) mark(lson); if(rson) mark(rson); t[x].rev=0; void rotate(int x) int old=t[x].f,fold=t[old].f,which=get(x); if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x; t[old].ch[which]=t[x].ch[which^1], t[t[old].ch[which]].f=old; t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold; pushup(old),pushup(x); void splay(int x) int v=0,u=x,fa; for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f; for(;v;--v) pushdown(sta[v]); for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) if(t[fa].f!=u) rotate(get(fa)==get(x)?fa:x); void Access(int x) for(int y=0;x;y=x,x=t[x].f) splay(x),rson=y,pushup(x); void makeroot(int x) Access(x),splay(x),mark(x); void link(int x,int y) makeroot(x),t[x].f=y; void cut(int x,int y) makeroot(x),Access(y),splay(y); t[t[y].ch[0]].f=0; t[y].ch[0]=0; pushup(y); void split(int x,int y) makeroot(x),Access(y),splay(y); #undef lson #undef rson op; int main() int i,j,n,m,ans=inf; // setIO("input"); scanf("%d%d",&n,&m); for(i=1;i<=m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c); sort(e+1,e+1+m,cmp); ufs.init(); for(i=1;i<=n;++i) op.t[i].val=inf; for(i=1;i<=m;++i) int x=e[i].u,y=e[i].v,c=e[i].c,_new=i+n; if(x==y) continue; if(ufs.merge(x,y)) op.t[_new].val=c; op.link(x,_new); op.link(_new,y); S.insert(c); else op.split(x,y); if(op.t[y].min<c) S.erase(S.find(op.t[y].min)); S.insert(c); int kk=op.t[y].id; int xx=e[kk-n].u; int yy=e[kk-n].v; op.cut(xx,kk); op.cut(yy,kk); op.t[_new].val=c; op.link(x,_new); op.link(_new,y); if(S.size()>=n-1) it=S.end(); it--; ans=min(ans,*(it)-*(S.begin())); printf("%d\n",ans); return 0;
以上是关于luogu 4234 最小差值生成树 LCT的主要内容,如果未能解决你的问题,请参考以下文章