bzoj 3669: [Noi2014]魔法森林

用lct模拟一下过程2333,蒟蒻就不乱说了。。

  1 #include<bits/stdc++.h>
  2 #define N 200005
  3 #define LL long long
  4 #define inf 0x3f3f3f3f
  5 #define ls c[x][0]
  6 #define rs c[x][1]
  7 using namespace std;
  8 inline int ra()
  9 {
 10     int x=0,f=1; char ch=getchar();
 11     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 12     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 13     return x*f;
 14 }
 15 int top,q[200005];
 16 int n,m,ans=inf;
 17 int mx[200005],val[200005];
 18 int father[200005],fa[200005],c[200005][2];
 19 bool rev[200005];
 20 struct node{int x,y,a,b;}e[100005];
 21 bool cmp(node a, node b){return a.a<b.a;}
 22 int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
 23 void update(int x)
 24 {
 25     mx[x]=x;
 26     if (val[mx[x]]<val[mx[ls]]) mx[x]=mx[ls];
 27     if (val[mx[x]]<val[mx[rs]]) mx[x]=mx[rs];
 28 }
 29 bool isroot(int x){return c[fa[x]][0]!=x && c[fa[x]][1]!=x;}
 30 bool lr(int x) {return c[fa[x]][1]==x;}
 31 void pushdown(int x)
 32 {
 33     if (rev[x])
 34     {
 35         rev[x]=0; rev[ls]^=1; rev[rs]^=1;
 36         swap(ls,rs);
 37     }
 38 }
 39 void rotate(int &x)
 40 {
 41     int y=fa[x],z=fa[y],l,r; bool nx=lr(x),ny=lr(y);
 42     if (!isroot(y)) c[z][ny]=x; fa[x]=z;
 43     c[y][nx]=c[x][!nx]; fa[c[x][!nx]]=y;
 44     c[x][!nx]=y; fa[y]=x; update(y); update(x);
 45 }
 46 void splay(int &x)
 47 {
 48     top=0; q[++top]=x;
 49     for (int i=x; !isroot(i); i=fa[i]) q[++top]=fa[i];
 50     while (top) pushdown(q[top--]);
 51     while (!isroot(x))
 52     {
 53         int y=fa[x],z=fa[y];
 54         if (!isroot(y))
 55         {
 56             if (lr(x)==lr(y)) rotate(y);
 57             else rotate(x);
 58         }
 59         rotate(x);
 60     }
 61 }
 62 void access(int x)
 63 {
 64     for (int t=0; x; t=x, x=fa[x])
 65         splay(x),c[x][1]=t,update(x);
 66 }
 67 void makeroot(int x)
 68 {
 69     access(x); splay(x); rev[x]^=1;
 70 }
 71 void link(int x, int y)
 72 {
 73     makeroot(x); fa[x]=y;
 74 }
 75 void cut(int x, int y)
 76 {
 77     makeroot(x); access(y); splay(y);
 78     c[y][0]=fa[x]=0; update(y);
 79 }
 80 int query(int x, int y)
 81 {
 82     makeroot(x); access(y); splay(y);
 83     return mx[y];
 84 }
 85 int main()
 86 {
 87     n=ra(); m=ra(); 
 88     for (int i=1; i<=n; i++) father[i]=i;
 89     for (int i=1; i<=m; i++)
 90         e[i].x=ra(),e[i].y=ra(),e[i].a=ra(),e[i].b=ra();
 91     sort(e+1,e+m+1,cmp); int tot=0;
 92     for (int i=1; i<=m; i++)
 93     {
 94         int x=e[i].x,y=e[i].y,a=e[i].a,b=e[i].b;
 95         if (find(x)==find(y))
 96         {
 97             int t=query(x,y);
 98             if (val[t]>e[i].b)
 99             {
100                 cut(t,e[t-n].x);
101                 cut(t,e[t-n].y);
102             }
103             else 
104             {
105                 if (find(1)==find(n)) ans=min(ans,e[i].a+val[query(1,n)]);
106                 continue;
107             }
108         }
109         else father[find(x)]=find(y);
110         val[n+i]=e[i].b; mx[n+i]=n+i;
111         link(x,n+i); link(y,n+i);
112         if (find(1)==find(n)) ans=min(ans,e[i].a+val[query(1,n)]);
113     }
114     if (ans==inf) puts("-1");
115     else cout<<ans;
116     return 0;
117 }
原文地址:https://www.cnblogs.com/ccd2333/p/6482499.html