lct模板
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 450005 6 #define M 300005 7 #define lc(x) ch[x][0] 8 #define rc(x) ch[x][1] 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 int f[N]; 12 int n,m,cnt; 13 struct node 14 { 15 int x,y,a1,a2; 16 friend bool operator < (node aa,node bb) 17 { 18 return aa.a1<bb.a1; 19 } 20 }bian[M]; 21 int fnd(int x) 22 { 23 if(x==f[x])return x; 24 return f[x]=fnd(f[x]); 25 } 26 int ch[N][2],zhi[N],mx[N],rev[N];int fa[N]; 27 bool isroot(int x) 28 { 29 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 30 } 31 void push_down(int x) 32 { 33 if(rev[x]) 34 { 35 rev[x]^=1;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1; 36 swap(ch[x][0],ch[x][1]); 37 } 38 return ; 39 } 40 void push_up(int x) 41 { 42 mx[x]=max(zhi[x],max(mx[lc(x)],mx[rc(x)])); 43 } 44 void rotate(int p) 45 { 46 int q=fa[p],y=fa[q],x=(ch[q][1]==p); 47 ch[q][x]=ch[p][x^1];fa[ch[q][x]]=q; 48 ch[p][x^1]=q; 49 fa[p]=y; 50 if(!isroot(q)) 51 { 52 if(ch[y][1]==q)ch[y][1]=p; 53 else ch[y][0]=p; 54 } 55 fa[q]=p; 56 push_up(q); 57 } 58 int q[M],top; 59 void splay(int x) 60 { 61 q[++top]=x; 62 for(int i=x;!isroot(i);i=fa[i]) 63 { 64 q[++top]=fa[i]; 65 } 66 while(top)push_down(q[top--]); 67 for(int y=fa[x];!isroot(x);rotate(x),y=fa[x]) 68 { 69 if(!isroot(y)) 70 { 71 if((lc(y)==x)^(lc(fa[y])==y))rotate(x); 72 else rotate(y); 73 } 74 } 75 push_up(x); 76 } 77 void access(int x) 78 { 79 for(int t=0;x;t=x,x=fa[x]) 80 { 81 splay(x);ch[x][1]=t;push_up(x); 82 } 83 } 84 void make_root(int x) 85 { 86 access(x);splay(x);rev[x]^=1; 87 } 88 void cut(int x,int y) 89 { 90 make_root(x); 91 access(y); 92 splay(y);ch[y][0]=fa[x]=0; 93 } 94 void link(int x,int y) 95 { 96 make_root(x);fa[x]=y; 97 } 98 void split(int x,int y) 99 { 100 // cout<<x<<' '<<y<<endl; 101 make_root(x);access(y);splay(y); 102 } 103 int find(int k,int x) 104 { 105 if(zhi[k]==x)return k; 106 if(mx[lc(k)]==x)return find(lc(k),x); 107 return find(rc(k),x); 108 } 109 int main() 110 { 111 int t1,t2,t3,t4;zhi[0]=0; 112 scanf("%d%d",&n,&m); 113 for(int i=1;i<=m;i++) 114 { 115 scanf("%d%d%d%d",&bian[i].x,&bian[i].y,&bian[i].a1,&bian[i].a2); 116 } 117 for(int i=1;i<=n+m;i++)f[i]=i; 118 sort(bian+1,bian+m+1); 119 int ans=0x3f3f3f3f;int now=0; 120 for(int i=1;i<=n;i++)zhi[i]=0; 121 for(int i=1;i<=m;i++)mx[i+n]=zhi[i+n]=bian[i].a2; 122 // cout<<mx[3]<<' '<<zhi[3]<<endl; 123 for(int i=1;i<=m;i++) 124 { 125 int a1=fnd(bian[i].x);int a2=fnd(bian[i].y); 126 if(a1!=a2) 127 { 128 link(bian[i].x,i+n);link(bian[i].y,i+n); 129 // cout<<bian[i].x<<' '<<bian[i].y<<' '<<i+n<<endl; 130 f[a1]=a2; 131 } 132 else 133 { 134 split(bian[i].x,bian[i].y); 135 if(mx[bian[i].y]>bian[i].a2) 136 { 137 int t=find(bian[i].y,mx[bian[i].y]); 138 cut(t,bian[t-n].x);cut(t,bian[t-n].y); 139 link(bian[i].x,i+n);link(bian[i].y,i+n); 140 } 141 } 142 if(fnd(1)==fnd(n)) 143 { 144 split(1,n); 145 // dfs(2); 146 ans=min(ans,bian[i].a1+mx[n]); 147 // cout<<bian[i].a1<<' '<<mx[n]<<endl; 148 } 149 } 150 if(ans==inf)puts("-1"); 151 else printf("%d\n",ans); 152 return 0; 153 }
动态最小生成树