• [BZOJ3237]连通图


    Description

    Input

    Output

    Sample Input

    4 5
    1 2
    2 3
    3 4
    4 1
    2 4
    3
    1 5
    2 2 3
    2 1 2

    Sample Output

    Connected
    Disconnected
    Connected

    HINT

    N<=100000 M<=200000 K<=100000

    自己yy的奇怪解法,首先我们可以发现一张图在联通的时候并查集祖先的$size=n$(这不是废话)

    然后就只要线段树分治随便维护一下并查集就完事了

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #include<map>
     6 #define ls node<<1
     7 #define rs node<<1|1
     8 #define M 200010
     9 #define mod 1000000007
    10 using namespace std;
    11 struct point{int u,v;}p[M],st[M];
    12 int n,m,k,top;
    13 int size[M],fa[M],f[M];
    14 vector<int>tag[M<<2];
    15 int find(int x) {
    16     while(x!=fa[x]) x=fa[x];
    17     return fa[x];
    18 }
    19 void insert(int node,int l,int r,int l1,int r1,int id) {
    20     if(l1<=l&&r1>=r) {
    21         tag[node].push_back(id);return;
    22     }int mid=(l+r)/2;
    23     if(l1<=mid) insert(ls,l,mid,l1,r1,id);
    24     if(r1>mid) insert(rs,mid+1,r,l1,r1,id);
    25 }
    26 void unionn(int x,int y) {
    27     x=find(x),y=find(y);
    28     if(x==y) return;
    29     if(size[x]<size[y]) swap(x,y);
    30     st[++top]=(point){x,y};
    31     size[fa[y]=x]+=size[y];
    32 }
    33 void Del(int now) {
    34     while(top!=now) {
    35         int x=st[top].u,y=st[top--].v;
    36         size[x]-=size[fa[y]=y];
    37     }
    38 }
    39 void Dfs(int node,int l,int r) {
    40     int now=top;
    41     for(int i=0;i<tag[node].size();i++)
    42         unionn(p[tag[node][i]].u,p[tag[node][i]].v);
    43     if(l==r) {
    44         int x=1;
    45         while(fa[x]!=x) x=fa[x];
    46         puts(size[x]==n?"Connected":"Disconnected");
    47     }
    48     else {
    49         int mid=(l+r)/2;
    50         Dfs(ls,l,mid),Dfs(rs,mid+1,r);
    51     }
    52     Del(now);
    53 }
    54 int main() {
    55     scanf("%d%d",&n,&m);
    56     for(int i=1;i<=n;i++) fa[i]=i,size[i]=1;
    57     for(int a,b,i=1;i<=m;i++) {
    58         scanf("%d%d",&a,&b);f[i]=1;
    59         p[i]=(point){a,b};
    60     }
    61     scanf("%d",&k);
    62     for(int i=1;i<=k;i++) {
    63         int c;scanf("%d",&c);
    64         for(int j=1;j<=c;j++) {
    65             int id;scanf("%d",&id);
    66             if(f[id]!=i) insert(1,1,k,f[id],i-1,id);
    67             f[id]=i+1;
    68         }
    69     }
    70     for(int i=1;i<=m;i++)
    71         if(f[i]!=k+1)
    72             insert(1,1,k,f[i],k,i);
    73     Dfs(1,1,k);
    74     return 0;
    75 }
  • 相关阅读:
    暴躁游戏

    时间记录表格
    好好生活
    JAVA环境的配置
    Java简介
    markdown学习

    Arduino
    Arduino
  • 原文地址:https://www.cnblogs.com/Slrslr/p/10042363.html
Copyright © 2020-2023  润新知