跟左神一起练算法(认识并查集)

介绍并查集比较清楚的文章

https://blog.csdn.net/zjy_code/article/details/80634149
在这里插入图片描述

上面的那篇文章写得不错,有一个例子可以让你深入理解并查集

一个数据结构理论上可以解决的同系列问题是无穷的,就好比,有了砖头,可以盖的建筑物是无穷的

找朋友

在社交的过程中,通过朋友,也能认识新的朋友。在某个朋友关系图中,假定 A 和 B 是朋友,B 和 C 是朋友,那么 A 和 C 也会成为朋友。即,我们规定朋友的朋友也是朋友。

现在,已知若干对朋友关系,询问某两个人是不是朋友。

请编写一个程序来解决这个问题吧。

输入格式

第一行:三个整数 n,m,p(n≤5000,m≤5000,p≤5000)分别表示有n 个人,m 个朋友关系,询问p 对朋友关系。

接下来 m 行:每行两个数Ai,Bi1≤Ai,Bi≤N,表示Ai​ 和 Bi具有朋友关系。

接下来 p 行:每行两个数,询问两人是否为朋友。

输出格式

输出共 p 行,每行一个Yes或No。表示第i个询问的答案为是否朋友。

扫描二维码关注公众号,回复: 8547674 查看本文章
样例输入

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

样例输出

Yes
Yes
No

题解::
#include<iostream>  
#include<algorithm>  
#include<string.h>  
using namespace std;  
int mark[5005],fa[5005];  
int get(int x)
{  
    if(fa[x]==x)
        return x;  
    return fa[x]=get(fa[x]);  
}  
int main()
{  
    int n,m,p;
    cin>>n>>m>>p;  
    int a,b;   
    memset(mark,0,sizeof(mark));  
    for(int i=1;i<=n;i++)
        fa[i]=i;  
    while(m--)
    {  
        cin>>a>>b;  
        a=get(a);  
        b=get(b);  
        if(a!=b)
        {  
            fa[a]=b;  
        }  
    }  
    for(int i=1;i<=p;i++)
    {  
        cin>>a>>b;  
        a=get(a);
        b=get(b);  
        if(a==b)
            mark[i]=1;  
    }  
    for(int i=1;i<=p;i++)
    {  
        if(mark[i])
            cout<<"Yes"<<endl;  
        else 
            cout<<"No"<<endl;  
    }  
    return 0;  
}

在这里插入图片描述

结论:

现在有一个N个元素的集合,如果现在查询的次数 + 合并的次数 >= N 我们就可以说单次查询和单次合并的平均时间复杂度是o(1)。这个结论在算法导论中花了40页去证明

左神说,有一个函数就算参数是10的80次方(目前人类所探明的宇宙的总原子数),返回值不会大于6,也就是说上面的结论还是o(6),也就是o(1),有一个人证明了25年。

发布了230 篇原创文章 · 获赞 28 · 访问量 9326

猜你喜欢

转载自blog.csdn.net/weixin_43767691/article/details/103413577
今日推荐