和最小差值生成树差不多
都是用lct维护生成树的题目
本题可以以a排序,再维护b(通常这种二维变量的题都差不多这样,先排序一维)
然后我tm竟然rotate手误打错了一点...调了好久..
然后关于pushup:关于最大值,最小值一类的信息要在pushup中赋初值,而异或和之类的可以不用
就是说不可以用引用中写法的来写..
#include<bits/stdc++.h> using namespace std; const int N=5e4+7; const int M=1e5+7; int n,m,st[N+M],tot,ans=1<<30,w[N+M]; struct edge{int a,b,u,v;bool operator <(const edge &x)const {return a<x.a;} }e[M]; struct tree{int ch[2],fa,mx=-1,id=-1;bool rev; }t[N+M]; void pushup(int x) {t[x].mx=w[x],t[x].id=x;if(t[x].ch[0]&&t[t[x].ch[0]].mx>t[x].mx) t[x].mx=t[t[x].ch[0]].mx,t[x].id=t[t[x].ch[0]].id;if(t[x].ch[1]&&t[t[x].ch[1]].mx>t[x].mx) t[x].mx=t[t[x].ch[1]].mx,t[x].id=t[t[x].ch[1]].id; } void rev(int x){swap(t[x].ch[0],t[x].ch[1]);t[x].rev^=1; } void pushdown(int x){if(t[x].rev){if(t[x].ch[0])rev(t[x].ch[0]);if(t[x].ch[1])rev(t[x].ch[1]);t[x].rev=0;} } bool nroot(int x){return (t[t[x].fa].ch[0]==x)||(t[t[x].fa].ch[1]==x); } void rotate(int x){int y=t[x].fa;int z=t[y].fa;bool k=t[y].ch[1]==x;if(nroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].fa=z;t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].fa=y;t[x].ch[k^1]=y;t[y].fa=x;pushup(y);pushup(x); } void splay(int x){int y=0,z=x;st[++y]=z;while(nroot(z))st[++y]=z=t[z].fa;while(y)pushdown(st[y--]);while(nroot(x)){y=t[x].fa;z=t[y].fa;if(nroot(y))(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);rotate(x);} } void access(int x){for(int y=0;x;y=x,x=t[x].fa){splay(x);t[x].ch[1]=y;pushup(x);} } void makeroot(int x){access(x);splay(x);rev(x); } void split(int x,int y){makeroot(x);access(y);splay(y); } int findroot(int x){access(x);splay(x);while(t[x].ch[0])x=t[x].ch[0];splay(x);return x; } void link(int x,int y){splay(x);t[x].fa=y; } bool check(int x,int y){makeroot(x);return findroot(y)==x; } int main(){cin>>n>>m;for(int i=1;i<=m;i++){scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].a,&e[i].b);}sort(e+1,e+1+m);for(int i=1;i<=m;i++){int u=e[i].u;int v=e[i].v;//t[i+n].mx=e[i].b,t[i+n].id=i+n;w[i+n]=e[i].b;if(u==v)continue;if(!check(u,v)){link(u,i+n),link(i+n,v);}else {split(u,v);int now=t[v].id,maxx=t[v].mx;if(e[i].b>maxx)continue;splay(now),t[t[now].ch[0]].fa=t[t[now].ch[1]].fa=0;link(u,i+n),link(i+n,v);}if(check(1,n)){split(1,n);ans=min(ans,t[n].mx+e[i].a);}}if(ans==1<<30)puts("-1");else printf("%d\n",ans);return 0; }