zoukankan      html  css  js  c++  java
  • 并查集+启发式合并+LCA思想 || 冷战 || BZOJ 4668

    题面:bzoj炸了,以后再补发

    题解:

    并查集,然后对于每个点记录它与父亲节点联通的时刻 tim ,答案显然是 u 到 v 的路径上最大的 tim 值。启发式合并,把 size 小的子树往大的上并,可以证明树高是 log N 的(我不会),

    所以最后套一个LCA思想,直接向上跳着找出路径上最大的 tim 值即为答案,时间复杂度O(N log N)。

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define max(a,b) ((a)>(b)?(a):(b))
     4 using namespace std;
     5 inline int rd(){
     6     int x=0;char c=getchar();
     7     while(c<'0'||c>'9')c=getchar();
     8     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     9     return x;
    10 }
    11 const int maxn=5e5+5,maxm=5e5+5;
    12 int N,M,o,u,v,ans=0,fa[maxn],tim[maxn],now=0,f1,f2,siz[maxn];
    13 int now_tim=0;
    14 inline int getf(int n){
    15     if(fa[n]==n) return n;
    16     return getf(fa[n]);
    17 }
    18 inline int getdep(int n){
    19     int cnt=0;
    20     while(fa[n]!=n){
    21         cnt++;
    22         n=fa[n];
    23     }
    24     return cnt;
    25 }
    26 int main(){
    27     N=rd(); M=rd();
    28     for(int i=1;i<=N;i++) fa[i]=i,siz[i]=1;
    29     while(M--){
    30         o=rd(); u=rd(); v=rd();
    31         u=u^ans; v=v^ans;
    32         if(o==0){
    33             now_tim++;
    34             f1=getf(u); f2=getf(v);
    35             if(f1!=f2){
    36                 if(siz[f1]>siz[f2]) swap(f1,f2);
    37                 siz[f2]+=siz[f1];
    38                 fa[f1]=f2;
    39                 tim[f1]=now_tim;
    40             }
    41         }
    42         else{
    43             f1=getf(u); f2=getf(v);
    44             ans=0;
    45             if(f1!=f2) {
    46                 printf("%d
    ",ans);
    47                 continue;
    48             }
    49             int dep1=getdep(u),dep2=getdep(v);
    50             if(dep1<dep2) swap(dep1,dep2),swap(u,v);            
    51             while(dep1>dep2){
    52                 dep1--;
    53                 ans=max(ans,tim[u]);
    54                 u=fa[u];
    55             }
    56             if(u!=v){
    57                 while(fa[u]!=fa[v]){
    58                     ans=max(ans,tim[u]);
    59                     ans=max(ans,tim[v]);
    60                     u=fa[u]; v=fa[v];
    61                 }
    62                 ans=max(ans,tim[u]);
    63                 ans=max(ans,tim[v]);                
    64             }
    65             printf("%d
    ",ans);
    66         }
    67     }
    68     return 0;
    69 }
    View Code

    By:AlenaNuna

  • 相关阅读:
    android 单位详解
    ViewFlipper的使用
    today is history,today is tomorrow
    Android2.1 和之后的版本 中的 drawable(hdpi,ldpi,mdpi) 的区别
    auto_ptr
    android编写Service入门
    Android程序完全退出的三种方法
    Android中Toast的用法简介
    安装android开发环境
    error C2850: 'PCH header file'
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/11623622.html
Copyright © 2011-2022 走看看