zoukankan      html  css  js  c++  java
  • bzoj3669 [Noi2014]魔法森林

    题目链接

    link cut tree

    先把边按a排序,用并查集维护连通块,一条边一条边往里面加,1和n连通就更新答案

    lct中需要维护当前链的边权最大值,把边权转化为点权:在边中间插一个点,边权赋值到点上

    若当前边的b<max(u,v)就要先cut掉u~v路径上的b最大的边

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<string>
      7 #include<cmath>
      8 #include<ctime>
      9 #include<queue>
     10 #include<stack>
     11 #include<map>
     12 #include<set>
     13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
     14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
     15 #define Clear(a,b) memset(a,b,sizeof(a))
     16 #define inout(x) printf("%d",(x))
     17 #define douin(x) scanf("%lf",&x)
     18 #define strin(x) scanf("%s",(x))
     19 #define LLin(x) scanf("%lld",&x)
     20 #define op operator
     21 #define CSC main
     22 typedef unsigned long long ULL;
     23 typedef const int cint;
     24 typedef long long LL;
     25 using namespace std;
     26 cint inf=2147483647;
     27 void inin(int &ret)
     28 {
     29     ret=0;int f=0;char ch=getchar();
     30     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
     31     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
     32     ret=f?-ret:ret;
     33 }
     34 struct bian
     35 {
     36     int u,v,a,b;
     37     void in(){inin(u),inin(v),inin(a),inin(b);}
     38     bool op < (const bian &rhs)const {return a<rhs.a;}
     39 }bi[100010];
     40 namespace lct
     41 {
     42     int ch[200020][2],w[200020],Max[200020],fa[200020],rev[200020];
     43     bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
     44     void maintain(int x)
     45     {
     46         Max[x]=x;
     47         if(w[Max[x]]<w[Max[ch[x][0]]])Max[x]=Max[ch[x][0]];
     48         if(w[Max[x]]<w[Max[ch[x][1]]])Max[x]=Max[ch[x][1]];
     49     }
     50     void rotate(int x)
     51     {
     52         int y=fa[x],z=fa[y];
     53         if(!isroot(y))ch[z][ch[z][1]==y]=x;
     54         fa[x]=z,fa[y]=x;
     55         int d=ch[y][1]==x;
     56         fa[ch[x][d^1]]=y;
     57         ch[y][d]=ch[x][d^1];
     58         ch[x][d^1]=y;
     59         maintain(y),maintain(x);
     60     }
     61     void down(int x)
     62     {
     63         if(rev[x])
     64         {
     65             swap(ch[x][0],ch[x][1]);
     66             rev[ch[x][0]]^=1;
     67             rev[ch[x][1]]^=1;
     68             rev[x]=0;
     69         }
     70     }
     71     int sta[100010],top;
     72     void splay(int x)
     73     {
     74         top=0;int xx=x;sta[++top]=xx;
     75         while(!isroot(xx))sta[++top]=fa[xx],xx=fa[xx];
     76         while(top)down(sta[top--]);
     77         while(!isroot(x))
     78         {
     79             int y=fa[x],z=fa[y];
     80             if(!isroot(y))
     81                 if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
     82                 else rotate(y);else ;
     83             rotate(x);
     84         }
     85     }
     86     void access(int x)
     87     {
     88         int temp=0;
     89         while(x)
     90         {
     91             splay(x);
     92             ch[x][1]=temp;
     93             maintain(x);
     94             temp=x,x=fa[x];
     95         }
     96     }
     97     void reverse(int x)
     98     {
     99         access(x),splay(x);rev[x]^=1;
    100     }
    101     void link(int x,int y)
    102     {
    103         reverse(x);fa[x]=y;
    104     }
    105     void cut(int x,int y)
    106     {
    107         reverse(x),access(y),splay(y),fa[x]=ch[y][0]=0;maintain(y);
    108     }
    109     int query(int x,int y)
    110     {
    111         reverse(x),access(y),splay(y);
    112         return Max[y];
    113     }
    114 }
    115 int n,m,fa[200020];
    116 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    117 int main()
    118 {
    119     inin(n),inin(m);re(i,1,n)fa[i]=i;
    120     re(i,1,m)bi[i].in();int ans=inf;
    121     sort(bi+1,bi+m+1);
    122     re(i,1,m)
    123     {
    124         int u=bi[i].u,v=bi[i].v,a=bi[i].a,b=bi[i].b;
    125         if(find(u)==find(v))
    126         {
    127             int temp=lct::query(u,v);
    128             if(lct::w[temp]>b)
    129             {
    130                 lct::cut(temp,bi[temp-n].u);
    131                 lct::cut(temp,bi[temp-n].v);
    132             }
    133             else 
    134             {
    135                 if(find(1)==find(n))ans=min(ans,a+lct::w[lct::query(1,n)]);
    136                 continue;
    137             }
    138         }
    139         else fa[find(u)]=find(v);
    140         lct::w[n+i]=b,lct::Max[n+i]=n+i;
    141         lct::link(u,n+i),lct::link(v,n+i);
    142         if(find(1)==find(n))ans=min(ans,a+lct::w[lct::query(1,n)]);
    143     }
    144     printf("%d
    ",ans==inf?-1:ans);
    145      return 0;
    146 }
  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5239938.html
Copyright © 2011-2022 走看看