首页 > 其他分享 >TZOJ 5782: 亲戚/6310: 亲戚2 并查集/路径压缩/优化

TZOJ 5782: 亲戚/6310: 亲戚2 并查集/路径压缩/优化

时间:2022-12-30 21:23:40浏览次数:51  
标签:输出 return r1 int 查集 亲戚 6310 find

先来看看代码清单:

(1)初始化

for(int i=1;i<=n;i++)f[i] = i; //初始化每个的爹是自己 

因为每个元素属于单独的一个集合,所以每个元素以自己作为结点

(2)寻找根结点编号并压缩路径

int find(int x)
{
        //如果第x个人的爹f[x]不是自己,那么就继续去寻找爹中爹,最终把自己的祖先认作自己的爹
    if(f[x]!=x) f[x] = find(f[x]); 
    return f[x];
}

(3)合并两个集合

void uon(int x,int y)
{
    x = find(x);y = find(y); //找到x,y的祖先
    f[y] = x; //让y的祖先认x的祖先作为爹 
}

(4)判断元素是否在同一个集合

int judge(int x,int y)
{
    x = find(x);
    y = find(y);
    if(x==y)return 1;
    else return 0;
}

(5)判断一个家族的人数,需要将合并函数uon改一下

void uon(int r1,int r2)
{
    if(a[r1]<a[r2])swap(r1,r2); //我们保证让人少的并到人多的
    f[r2] = r1; //r2并入到r1
    a[r1] += a[r2]; //把两个家族的人加上到r1家族中
}

5782: 亲戚 

描述

或许你并不知道,你的某个朋友是你的亲戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孙子。如果能得到完整的家谱,判断两个人是否是亲戚应该是可行的,但如果两个人的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系实非人力所能及。在这种情况下,最好的帮手就是计算机。为了将问题简化,你将得到一些亲戚关系的信息,如Marry和Tom是亲戚,Tom和Ben是亲戚,等等。从这些信息中,你可以推出Marry和Ben是亲戚。请写一个程序,对于我们的关于亲戚关系的提问,以最快的速度给出答案。

 

 

输入

 

 

输入由两部分组成。

第一部分以N,M开始。N为问题涉及的人的个数(1≤N≤20000)。这些人的编号为1,2,3,…, N。下面有M行(1≤M≤1000000),每行有两个数ai,bi,表示已知ai和bi是亲戚。

第二部分以Q开始。以下Q行有Q个询问(1≤ Q ≤1000000),每行为ci,di,表示询问ci和di是否为亲戚。

 

 

输出

 

 

对于每个询问ci,di,输出一行:若ci和di为亲戚,则输出“Yes”,否则输出“No”。

 

 

样例输入

 

10 7
2 4
5 7
1 3
8 9
1 2
5 6
2 3
3
3 4
7 10
8 9

样例输出

Yes
No
Yes

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[20005];
 4 int n,m,q;
 5 int find(int x)
 6 {
 7     if(f[x]!=x) f[x] = find(f[x]);
 8     return f[x];
 9 }
10 void uon(int r1,int r2)
11 {
12     f[r2] = r1;
13 }
14 int judge(int x,int y)
15 {
16     x = find(x);
17     y = find(y);
18     if(x==y)return 1;
19     else return 0;
20 }
21 int main()
22 {
23     cin>>n>>m;
24     for(int i=1;i<=n;i++)f[i] = i;
25     for(int i=1;i<=m;i++)
26     {
27         int x,y;
28         scanf("%d %d",&x,&y);
29         int r1 = find(x);
30         int r2 = find(y);
31         if(r1!=r2)uon(r1,r2);
32     }
33     cin>>q;
34     while(q--)
35     {
36         int x,y;
37         scanf("%d %d",&x,&y);
38         if(judge(x,y))printf("Yes\n");
39         else printf("No\n");
40     }
41      return 0;
42 }

 

6310: 亲戚2

描述

 

若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的某个人所在家族的人数。

规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

 

输入

 

第一行:三个整数n,(n≤100,000,m≤200,000),分别表示有n个人,m个信息。

以下m行:信息包含两种形式:

M a b:表示a和b具有亲戚关系。

Q a:要求输出a所在家族的人数。

 

输出

 

要求输出a所在家族的人数。

 

样例输入

 

5 10
M 3 2
Q 4
M 1 2
Q 4
M 3 2
Q 1
M 3 1
Q 5
M 4 2
Q 4

样例输出

 

1
1
3
1
4

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[100005],a[100005];
 4 int n,m,q;
 5 char c;
 6 int find(int x)
 7 {
 8     if(f[x]!=x) f[x] = find(f[x]);
 9     return f[x];
10 }
11 void uon(int r1,int r2)
12 {
13     if(a[r1]<a[r2])swap(r1,r2);
14     f[r2] = r1;
15     a[r1] += a[r2]; //把两个家族的人加上 
16 }
17 int judge(int x,int y)
18 {
19     x = find(x);
20     y = find(y);
21     if(x==y)return 1;
22     else return 0;
23 }
24 int main()
25 {
26     scanf("%d %d",&n,&m);
27     for(int i=1;i<=n;i++)f[i] = i,a[i] = 1;
28     for(int i=1;i<=m;i++)
29     {
30         scanf("\n%c",&c);
31         if(c=='M')
32         {
33             int x,y;
34             scanf("%d %d",&x,&y);
35             int r1 = find(x);
36             int r2 = find(y);
37             if(r1!=r2)uon(r1,r2);
38         }
39         else
40         {
41             int x;
42             scanf("%d",&x);
43             printf("%d\n",a[find(x)]);
44         }
45     }
46 
47      return 0;
48 }

 

标签:输出,return,r1,int,查集,亲戚,6310,find
From: https://www.cnblogs.com/jyssh/p/17015828.html

相关文章

  • 中国亲戚关系计算器
    中国亲戚关系计算器。该项目实现了中国亲戚关系及称呼之间的换算,可以将中国复杂的亲戚关系及称呼通过计算器的方式简单的运算出来。在线使用:https://passer-by.com/relati......
  • P1024 [NOI2001] 食物链【种类并查集】
    题意P1024简化题意:给定\(n\)和\(k(n\leqslant5\times10^4,k\leqslant10^5)\),表示有\(n\)个动物,\(k\)个描述,其中:\(n\)个动物分别属于\(A,B,C\)中的一种,定义......
  • 数据结构:并查集 学习笔记
    数据结构:并查集学习笔记基础知识并查集是一种树形数据结构。在全国青少年信息学奥林匹克系列竞赛大纲中难度为6,是提高级中学习的数据结构。并查集的基本操作:查询一......
  • 并查集
    title:并查集date:2022-11-1511:49:57tags:算法本文章遵守知识共享协议CC-BY-NC-SA,转载时须在文章的任一位置附上原文链接和作者署名(rickyxrc)。推荐在我的个人博......
  • 带权并查集
    被老师拖来讲数据结构了带权并查集带权并查集,顾名思义,就是在并查集中加上权值,点权和边权实际上是等价的,因为并查集实际上是多棵树组成的,树上的每个节点,都只有一个父节点,......
  • 一个并查集对象
    实现并查集的查找、合并、类别sizeclassUF{constructor(n){this.parent=Array(n)this.size=[]for(leti=0;i<n;i++){......
  • hdu:继续畅通工程(kruskal的MST并查集实现)
    ProblemDescription省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表......
  • hdu:小希的迷宫(并查集)
    ProblemDescription上次Gardon的迷宫城堡小希玩了很久,现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说......
  • 图论-堆-并查集-2503. 矩阵查询可获得的最大分数
    2503.矩阵查询可获得的最大分数DescriptionDifficulty:困难RelatedTopics:给你一个大小为mxn的整数矩阵grid和一个大小为k的数组queries。找出一个大小......
  • 现在有一个并查集,你需要完成合并和查询操作。
    输入格式:第一行包含两个整数N,M,表示共有N个元素和M个操作。接下来M行,每行包含三个整数zi,xi,yi。当zi=1时,将xi与yi所在的集合合并。当zi=2时,输出xi与yi......