zoukankan      html  css  js  c++  java
  • [LOJ121]动态图连通性

    题目描述

    这是一道被离线爆艹的模板题。

    你要维护一张无向简单图。你被要求加入删除一条边及查询两个点是否连通。

    • 0:加入一条边。保证它不存在。
    • 1:删除一条边。保证它存在。
    • 2:查询两个点是否联通。

    输入格式

    输入的第一行是两个数 N MN MN M。N≤5000,M≤500000N leq 5000,M leq 500000N5000,M500000。

    接下来 MMM 行,每一行三个数 op,x,ymathit{op}, x, yop,x,y。opmathit{op}op 表示操作编号。

    输出格式

    对于每一个 op=2mathit{op}=2op=2 的询问,输出一行 YN ,表示两个节点是否连通。

    样例

    样例输入 1

    200 5
    2 123 127
    0 123 127
    2 123 127
    1 127 123
    2 123 127

    样例输出 1

    N
    Y
    N

    样例输入 2

    4 10
    0 1 2
    0 2 3
    0 3 1
    2 1 4
    0 4 3
    2 1 4
    1 2 3
    2 1 4
    1 1 3
    2 1 4

    样例输出 2

    N
    Y
    Y
    N

    数据范围与提示

    对于数据点 1,N≤200,M≤200N leq 200,M leq 200N200,M200。
    对于数据点 2,N=5,M≤30N=5,M leq 30N=5,M30。
    对于数据点 3,N=10,M≤1000N=10,M leq 1000N=10,M1000,其中查询的次数 ≥900geq 900900 次。
    对于数据点 4,N=300,M≤50000N=300,M leq 50000N=300,M50000。
    对于数据点 5,N=5000,M≤200000N=5000,M leq 200000N=5000,M200000,没有操作 1,其中约 70%70 \%70% 是操作 2。
    对于数据点 6,N=5000,M≤200000N=5000,M leq 200000N=5000,M200000,没有操作 1,其中约 70%70 \%70% 是操作 0。
    对于数据点 7、8,N=100,M≤500000N=100,M leq 500000N=100,M≤500000。对于数据点 9,N=5000,M≤500000N=5000,M leq 500000N=5000,M≤500000,图是一棵树,其直径 ≤6 leq 6≤6。对于数据点 10, N=5000,M≤500000N=5000,M leq 500000N=5000,M≤500000,图是一棵树,其每个点度数 ≤4 leq 4≤4。

    P.S. 其实 9 是菊花,10 是单链,而没有放随机树的点...

    按时间(即操作顺序)建立线段树,可以发现每条边存在的时间是一段区间也就是说会影响到一段时间内的查询

    然后用按大小合并的并查集维护一下即可

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<map>
     6 #define ls node<<1
     7 #define rs node<<1|1
     8 #define M 500010
     9 using namespace std;
    10 int n,m,top,cnt1,cnt2;
    11 int fa[M],f[M],size[M];
    12 bool vis[M];
    13 map<int,int>edge[M];
    14 struct point{int u,v;}CG[M],a[M],st[M],Q[M];
    15 vector<int>tag[M<<2];
    16 void insert(int node,int l,int r,int l1,int r1,int id) {
    17     if(l1<=l&&r1>=r) return void(tag[node].push_back(id));
    18     int mid=(l+r)/2;
    19     if(l1<=mid) insert(ls,l,mid,l1,r1,id);
    20     if(r1>mid) insert(rs,mid+1,r,l1,r1,id);
    21 }
    22 int find(int x) {
    23     while(fa[x]!=x) x=fa[x];
    24     return x;
    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[x]=y]+=size[x];
    32 }
    33 void del(int now) {
    34     while(top>now) {
    35         int x=st[top].u,y=st[top--].v;
    36         size[y]-=size[fa[x]=x];
    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(CG[tag[node][i]].u,CG[tag[node][i]].v);
    43     }
    44     if(l==r) {
    45         if(vis[l]) 
    46             puts(find(Q[l].u)==find(Q[l].v)?"Y":"N");
    47     }
    48     else{
    49         int mid=(l+r)/2;
    50         Dfs(ls,l,mid),Dfs(rs,mid+1,r);
    51     }del(now);
    52 }
    53 int main() {
    54     scanf("%d%d",&n,&m);
    55     for(int i=1;i<=n;i++) fa[i]=i,size[i]=1;
    56     for(int i=1;i<=m;i++) {
    57         int opt,x,y;
    58         scanf("%d%d%d",&opt,&x,&y);
    59         if(x>y) swap(x,y);
    60         if(opt==0) {
    61             if(f[edge[x][y]]) continue;
    62             edge[x][y]=++cnt1;
    63             a[cnt1]=(point){x,y};
    64             f[edge[x][y]]=i;
    65         }
    66         else if(opt==1) {
    67             int id=edge[x][y];
    68             CG[++cnt2]=(point){x,y};
    69             insert(1,1,m,f[id],i,cnt2);
    70             f[id]=0;
    71         }
    72         else Q[i]=(point){x,y},vis[i]=true;
    73     }
    74     for(int i=1;i<=cnt1;i++)if(f[i]) {
    75             CG[++cnt2]=(point){a[i].u,a[i].v};
    76             insert(1,1,m,f[i],m,cnt2);
    77         }
    78     Dfs(1,1,m);
    79     return 0;
    80 }
  • 相关阅读:
    Alfred上可提高工作效率的Workflow推荐
    局部性原理——各类优化的基石
    持续学习——程序猿的军备竞赛
    http://regex.alf.nu/ 非标准答案
    13总结
    Ubuntu下python安装mysqldb(驱动)
    北大ACM试题分类+部分解题报告链接
    poj 3253 Fence Repair(优先队列+huffman树)
    Centos/Fedora下安装Twisted,failed with error code 1 in /tmp/pip-build-H1bj8E/twisted/解决方法
    关于command 'gcc' failed with exit status 1 解决方法
  • 原文地址:https://www.cnblogs.com/Slrslr/p/10027191.html
Copyright © 2011-2022 走看看