首页 > 代码库 > lct模板

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 }

动态最小生成树

lct模板