• [BZOJ4668]冷战


    题目大意:
      一个$n(nle5 imes10^5)$个点的图,初始时没有边,有$m(mle5 imes10^5)$次操作,操作包含以下两种:
        1.在$u,v$之间连一条无向边;
        2.询问$u,v$经过几次操作1之后连通。

    思路:
      并查集按秩合并,不路径压缩。询问时暴力LCA求路径最大值。时间复杂度$O(mlog n)$。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 };
    11 const int N=500001;
    12 int par[N],w[N],h[N],dep[N];
    13 int find(const int &x) {
    14     if(par[x]==x) return x;
    15     const int ret=find(par[x]);
    16     dep[x]=dep[par[x]]+1;
    17     return ret;
    18 }
    19 inline int query(int u,int v) {
    20     int ret=0;
    21     while(u!=v) {
    22         if(dep[u]<dep[v]) std::swap(u,v);
    23         ret=std::max(ret,w[u]);
    24         u=par[u];
    25     }
    26     return ret;
    27 }
    28 int main() {
    29     const int n=getint();
    30     for(register int i=1;i<=n;i++) h[par[i]=i]=1;
    31     for(register int m=getint(),ans=0,cnt=0;m;m--) {
    32         const int opt=getint(),u=getint()^ans,v=getint()^ans;
    33         if(opt==0) {
    34             int x=find(u),y=find(v);
    35             if(h[x]>h[y]) std::swap(x,y);
    36             h[par[x]=y]=std::max(h[y],h[x]+1);
    37             w[x]=++cnt;
    38         }
    39         if(opt==1) printf("%d
    ",ans=find(u)!=find(v)?0:query(u,v));
    40     }
    41     return 0;
    42 }
  • 相关阅读:
    五、批量插入
    四、操作BLOB类型字段
    三、使用PreparedStatement实现CRUD操作
    二、获取数据库连接
    一、JDBC概述
    最短平均码长(挑出假硬币问题的解法)
    信息量和信息熵
    洛谷P2114
    Servlet续(HttpServletRequest类和HttpServletResponse类)
    Servlet
  • 原文地址:https://www.cnblogs.com/skylee03/p/8624522.html
Copyright © 2020-2023  润新知