并查集的删除操作

Posted lmcc1108

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集的删除操作相关的知识,希望对你有一定的参考价值。

C - Junk-Mail Filter  HDU - 2473 

题目大意:就是一堆信件,然后有两个操作,一个是把一堆信件归在一个文件夹,一个就是把一个信件从文件夹中取出,最后问有多少个文件夹,一开始所有信件都是单独的文件夹。

其实就是一个简单的并查集删除的操作,当删除时就创建新的结点来代替它,要注意的是数组的范围,虽然信件只有10的5次方,但是操作有10的6次方,因为删除时还得创建新节点,所以数组一定要开大,不然不是WR就是TL。最后的输出可以直接用set,也可以用数组标记信件是归在哪个文件夹,注意的是后面创建的结点是虚拟的,真实的信件有对它们的映射,所以最后统计时只考虑真实信件。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<set>
 4 using namespace std;
 5 struct Email{
 6     int id,gen;
 7 }em[1201108];//要够大 
 8 int n,m;
 9 int gui(int x);
10 void bing(int x,int y);
11 void del(int x);
12 int main()
13 {
14     int i,x,y,test=0;
15     char c;
16     while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
17     {
18         int N=n;
19         set<int> s;
20         for(i=0;i<n;i++)
21         {
22             em[i].id=i;
23             em[i].gen=i;
24         }//初始自己映射自己,自己是自己的根节点。。。。 
25         while(m--)
26         {
27             cin>>c;
28             if(c==M)
29             {
30                 scanf("%d%d",&x,&y);
31                 bing(em[x].id,em[y].id);
32             }
33             else
34             {
35                 scanf("%d",&x);
36                 del(x);
37             }
38         }
39         for(i=0;i<N;i++)//只考虑真实信件 
40             s.insert(gui(em[i].id));//每个集合的根节点只记录一次 
41         printf("Case #%d: %d
",++test,s.size());
42     }
43     return 0;
44 }
45 int gui(int x)
46 {
47     if(em[x].gen==x)
48         return x;
49     return em[x].gen=gui(em[x].gen);
50 }
51 void bing(int x,int y)//对节点所映射的节点进行并操作 
52 {
53     int bx=gui(x);
54     int by=gui(y);
55     if(bx!=by)
56         em[by].gen=bx;
57     return ;
58 }
59 void del(int x)//创造虚拟节点来代替原来节点 
60 {
61     em[x].id=n;//节点映射到新创建的虚拟节点 
62     em[n].gen=n;
63     n++;
64     return ;
65 }

 

以上是关于并查集的删除操作的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2473 Junk-Mail Filter (并查集的删除操作)

朋友(并查集的删除操作 可看作是插入操作的逆序)

❤️数据结构入门❤️(2 - 5)- 并查集

Restructuring Company和Almost Union-Find 并查集的区间合并与并查集的删除

并查集分析与扩展

Nowcoder 106 C.Professional Manager(统计并查集的个数)