NOI2014魔法森林

Orz 神奇性质 LCT板子

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 50010
  4 #define RG register 
  5 #define IL inline 
  6 #define rep(a,b,c) for(register int (a)=(b);(a)<=(c);++(a))
  7 #define INF (1<<30)
  8 IL bool isitdigit(char c){    return c>='0'&&c<='9';    }
  9 IL int read()
 10 {
 11     RG int s;RG char c;
 12     while(!isitdigit(c=getchar()));
 13     for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0');
 14     return s;
 15 }
 16 IL int minify(int & a,int b){    return a<=b? a:a=b;    }
 17 IL void swapt(int & a,int &b){    RG int t=a;a=b,b=t;    }
 18 
 19 
 20 int n,m,ans=INF;
 21 
 22 
 23 int findset[N];
 24 int find(int x){    return x==findset[x]? x:findset[x]=find(findset[x]);    }
 25 IL int judge(int a,int b){ return find(a)==find(b);    }
 26 IL int combine(int a,int b){    findset[findset[a]]=findset[b];    }
 27 
 28 
 29 struct edge
 30 {
 31     int f,t,a,b,e;
 32     edge(int ff=0,int tt=0,int aa=0,int bb=0,int ee=0):f(ff),t(tt),a(aa),b(bb),e(ee){}
 33     const bool operator < (const edge another)
 34     const{    return a<another.a;    } 
 35 }eg[2*N];
 36 
 37 
 38 int fa[3*N],son[3*N][2],mx[3*N],rev[N*3],tot;
 39 IL bool isroot(int o){    return son[fa[o]][1]!=o&&son[fa[o]][0]!=o;    }
 40 IL int side(int o){    return son[fa[o]][1]==o;    }
 41 IL void add(int f,int d,int s){    fa[s]=f,son[f][d]=s;    }
 42 IL void reverse(int o)
 43 {
 44     if(!o) return;rev[o]^=1;
 45     swapt(son[o][1],son[o][0]);
 46 }
 47 IL void pushdown(int o)
 48 {
 49     if(!rev[o])return;rev[o]=0;
 50     reverse(son[o][1]);reverse(son[o][0]);
 51 }
 52 IL void pushup(int o)
 53 {    
 54     if(o>n) mx[o]=o-n; else mx[o]=0;
 55     if(son[o][1]) mx[o]=eg[mx[o]].b>eg[mx[son[o][1]]].b? mx[o]:mx[son[o][1]];
 56     if(son[o][0]) mx[o]=eg[mx[o]].b>eg[mx[son[o][0]]].b? mx[o]:mx[son[o][0]];    
 57 }
 58 IL int newnode(int t){    mx[++tot]=t;return tot;    }
 59 IL void ronate(int o)
 60 {
 61     RG int f=fa[o],g=fa[f],d=side(o);
 62     if(isroot(f)) fa[o]=g;else add(g,side(f),o);
 63     add(f,d,son[o][d^1]);add(o,d^1,f);
 64     pushup(f);pushup(o);
 65 }
 66 IL void splay(int o)
 67 {
 68     static int que[2*N],top;que[top=1]=o;
 69     for(RG int p=o;!isroot(p);p=fa[p]) que[++top]=fa[p];
 70     for(RG int p=top;p;--p) pushdown(que[p]);
 71     for(RG int f;!isroot(o);ronate(o))
 72         if(!isroot(f=fa[o]))
 73             ronate(side(o)^side(f)? o:f);
 74 }
 75 IL void aces(int o){    for(RG int f=0;o;son[o][1]=f,pushup(o),f=o,o=fa[o]) splay(o);    }
 76 IL void makeroot(int o){    aces(o);splay(o);reverse(o);    }
 77 IL void link(int a,int b){    makeroot(a);fa[a]=b;    }
 78 IL void cut(int a,int b){    makeroot(a);aces(b);splay(a);son[a][1]=fa[b]=0;pushup(a);    }
 79 IL int query(int a,int b){    makeroot(a);aces(b);splay(a);return mx[a];    }
 80 
 81 
 82 int main()
 83 {
 84     freopen("magicalforest.in","r",stdin);
 85     freopen("magicalforest.out","w",stdout);
 86     tot=n=read(),m=read();
 87     rep(i,1,m)
 88     {
 89         RG int f=read(),t=read(),a=read(),b=read();
 90         eg[i]=(edge){f,t,a,b,0};
 91     }
 92     rep(i,1,n) findset[i]=i;
 93     sort(eg+1,eg+m+1);
 94     ans=INF;
 95     rep(i,1,m)
 96     {
 97         RG int res=INF;
 98         RG edge & now=eg[i];now.e=newnode(i);
 99         if(now.f==now.t) continue;
100         if(judge(now.f,now.t))
101         {
102             RG edge & temp=eg[query(now.f,now.t)];
103             if(temp.b>=now.b)
104             {
105                 cut(temp.f,temp.e);
106                 cut(temp.e,temp.t);
107                 link(now.f,now.e);
108                 link(now.e,now.t);    
109             }
110         }
111         else 
112         {
113             combine(now.f,now.t);
114             link(now.f,now.e);
115             link(now.e,now.t);
116         }
117         if(judge(1,n))
118         {
119             RG edge& temp=eg[query(1,n)];
120             res=now.a+temp.b;
121         }
122         minify(ans,res);
123     }
124     if(ans==INF) printf("-1");
125     else printf("%d",ans);
126     return 0;
127 }

 

posted @ 2018-07-02 15:58  咸鱼炒蒟蒻  阅读(139)  评论(0编辑  收藏  举报