zoukankan      html  css  js  c++  java
  • 洛谷 2387 NOI2014魔法森林 LCT

    【题解】

      我们先把边按照$a$值从小到大排序,并按照这个顺序加边。

      如果当前要加入的边连接的两点$u$与$v$已经是连通的,那么直接加入这条边就会出现环。这时我们需要删除这个环中$b$值最大的边。因此我们需要维护区间最大值,以及最大值的位置。

      如果当前$1$与$n$已经连通,就更新$ans$,当前从$1~n$的代价是$ai+val[querymax(1,n)]$;

      为了方便处理,我们可以把边开成点,即加边的时候多开一个表示这条边的点,在上面记录边权等信息。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define N (500010)
      4 #define inf (2e9)
      5 #define ls (c[u][0])
      6 #define rs (c[u][1])
      7 using namespace std;
      8 int n,m,ans;
      9 inline int read(){
     10     int k=0,f=1; char c=getchar();
     11     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
     12     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
     13     return k*f;
     14 }
     15 struct edge{int u,v,a,b;}e[N];
     16 struct Link_cut_tree{
     17     int top,c[N][2],fa[N],rev[N],q[N],maxpos[N],val[N];
     18     inline void pushdown(int u){
     19         if(rev[u]) rev[ls]^=1,rev[rs]^=1,rev[u]^=1,swap(ls,rs);
     20     }
     21     inline void pushup(int u){
     22         maxpos[u]=u;
     23         if(val[maxpos[ls]]>val[maxpos[u]]) maxpos[u]=maxpos[ls];
     24         if(val[maxpos[rs]]>val[maxpos[u]]) maxpos[u]=maxpos[rs];
     25     }
     26     inline bool isroot(int u){
     27         return c[fa[u]][0]!=u&&c[fa[u]][1]!=u;
     28     }
     29     inline bool which(int u){
     30         return c[fa[u]][1]==u;
     31     }
     32     void rotate(int u){
     33         int f=fa[u],gf=fa[f],wh=which(u);
     34         if(!isroot(f)) c[gf][which(f)]=u;
     35         fa[u]=gf; fa[f]=u; fa[c[u][wh^1]]=f;
     36         c[f][wh]=c[u][wh^1]; c[u][wh^1]=f;
     37         pushup(f); pushup(u);
     38     }
     39     void splay(int u){
     40         q[top=1]=u;
     41         for(int i=u;!isroot(i);i=fa[i]) q[++top]=fa[i];
     42         for(int i=top;i;i--) pushdown(q[i]);
     43         while(!isroot(u)){
     44             if(!isroot(fa[u])) rotate(which(fa[u])==which(u)?fa[u]:u);
     45             rotate(u);
     46         }
     47         pushup(u);
     48     }
     49     void access(int u){
     50         for(int son=0;u;son=u,u=fa[u]) splay(u),c[u][1]=son,pushup(u);
     51     }
     52     void makeroot(int u){
     53         access(u); splay(u); rev[u]^=1;
     54     }
     55     int find(int u){
     56         access(u); splay(u);
     57         while(ls) u=ls;
     58         return u;
     59     }
     60     void split(int x,int y){
     61         makeroot(x); access(y); splay(y);
     62     }
     63     void cut(int x,int y){
     64         split(x,y);
     65         c[y][0]=fa[x]=0;
     66         pushup(y);
     67     }
     68     void link(int x,int y){
     69         makeroot(x); fa[x]=y;
     70     }
     71     int query(int x,int y){
     72         makeroot(x); access(y); splay(y);
     73         return maxpos[y];
     74     }
     75 }t;
     76 bool cmp(edge x,edge y){
     77     return x.a<y.a;
     78 }
     79 int main(){
     80     ans=inf;
     81     n=read(); m=read();
     82     for(int i=1;i<=m;i++) 
     83         e[i].u=read(),e[i].v=read(),e[i].a=read(),e[i].b=read();
     84     sort(e+1,e+m+1,cmp);
     85     for(int i=1;i<=m;i++){
     86         int u=e[i].u,v=e[i].v,a=e[i].a,b=e[i].b;
     87         if(t.find(u)==t.find(v)){
     88             int pos=t.query(u,v);
     89             if(t.val[pos]>b){
     90                 t.cut(pos,e[pos-n].u);
     91                 t.cut(pos,e[pos-n].v);
     92             }
     93             else{
     94                 if(t.find(1)==t.find(n)) ans=min(ans,a+t.val[t.query(1,n)]);
     95                 continue;
     96             }
     97         }
     98         t.val[n+i]=b; t.maxpos[n+i]=n+i;
     99         t.link(u,n+i); t.link(v,n+i);
    100         if(t.find(1)==t.find(n)) ans=min(ans,a+t.val[t.query(1,n)]);
    101     }
    102     if(ans==inf) puts("-1");
    103     else printf("%d
    ",ans);
    104     return 0;
    105 }
    View Code
  • 相关阅读:
    [SCOI2012]滑雪与时间胶囊
    [SCOI2012]喵星球上的点名
    SDOI2012 Round1 day2 拯救小云公主(dis)解题报告
    SDOI2012 Round1 day2 象棋(chess)解题报告
    SDOI2012 Round1 day2 集合(set)解题报告
    [Sdoi2014]数数[数位dp+AC自动机]
    [NOI2013]快餐店
    java 日期的格式化 输入/输出
    elastic search 查询语句
    elasticsearch数据迁移——elasticsearch-dump使用
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8277550.html
Copyright © 2011-2022 走看看