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 }
  • 相关阅读:
    Macaca拓展自己控件的方法
    pyparsing:定制自己的解析器
    利用 Traceview 精准定位启动时间测试的异常方法 (工具开源)
    Jenkins插件开发
    一个简陋的高并发请求脚本的演进过程
    python 自定义回调函数
    默认端口
    基本数据类型封装类比较
    grep命令和tail命令
    idea 拉取git新分支
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5239938.html
Copyright © 2011-2022 走看看