zoukankan      html  css  js  c++  java
  • 可以删点的并查集

    如题。

    方法一:LCT!细节挺多,略。

    方法二:如题(废话。。)

    如果照传统的方法,比如1,2,3在一起要把1删掉,要保证1的爸爸和2,3以后不一样,如果1不是根节点就直接$fa[1]=1$,否则需要改所有的儿子。

    上面的问题在于删掉根节点的操作过于冗杂,也就是说想一个办法使得1-n中没有一个点作为根节点,那就新申请n+1-2n做1-n的根,这样就不可能会有谁做根节点。

    慢着,如果某个点被删掉,他的爸爸要变,又不能变成自己,咋整?再申请!

    以下是:给一个图,保证每个点度数不超过10,一开始所有点都下线,每次可以选一个点上线和周围上线的点所在集合合并,或者选一个点下线,或者查某个点所在集合的大小。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 #include<algorithm>
     6 //#include<queue>
     7 //#include<iostream>
     8 using namespace std;
     9 
    10 int n,m,q;
    11 #define maxn 200011
    12 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2;
    13 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
    14 void insert(int x,int y) {in(x,y); in(y,x);}
    15 
    16 int ufs[maxn*3],size[maxn*3]; bool live[maxn];
    17 int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
    18 void Union(int x,int y)
    19 {
    20     x=find(x),y=find(y); if (x==y) return;
    21     ufs[x]=y; size[y]+=size[x];
    22 }
    23 
    24 int main()
    25 {
    26     scanf("%d%d%d",&n,&m,&q);
    27     for (int i=1,x,y;i<=m;i++)
    28     {
    29         scanf("%d%d",&x,&y);
    30         insert(x,y);
    31     }
    32     for (int i=1;i<=n;i++) ufs[i]=i+n,ufs[i+n]=i+n,size[i+n]=1; int tot=n+n;
    33     char id;int x;
    34     while (q--)
    35     {
    36         while ((id=getchar())!='i' && id!='q' && id!='o'); scanf("%d",&x);
    37         if (id=='i')
    38         {
    39             live[x]=1;
    40             for (int i=first[x];i;i=edge[i].next)
    41             {
    42                 const Edge &e=edge[i]; if (!live[e.to]) continue;
    43                 Union(x,e.to);
    44             }
    45         }
    46         else if (id=='o')
    47         {
    48             live[x]=0; int y=find(x); size[y]--;
    49             ufs[x]=++tot; ufs[tot]=tot; size[tot]=1;
    50         }
    51         else
    52         {
    53             x=find(x);
    54             printf("%d
    ",size[x]);
    55         }
    56     }
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    用OFC画多条曲线
    C# 写Windows服务
    asp.net遍历文件夹和文件
    Sqlserver常用函数收集之truncate table
    如何构建多用户商城
    asp.net 获取客户端IP
    Jquery从头学起第四讲
    c#相对路径和系统路径
    JQuery获取URL
    【转】 ASP.NET session 保存到数据库
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8340878.html
Copyright © 2011-2022 走看看