自学内容网 自学内容网

图论day59|并查集理论基础、107.寻找存在的路径(卡码网)

图论day59|并查集理论基础、107.寻找存在的路径(卡码网)

并查集理论基础

在这里插入图片描述

  • 使用场景:

    当需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集

  • 主要功能:

    • 将两个元素添加到一个集合
    • 判断两个元素在不在同一个集合
  • 代码模板

  int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
  vector<int> father = vector<int> (n, 0); // C++里的一种数组结构
  
  // 并查集初始化
  void init() {
      for (int i = 0; i < n; ++i) {
          father[i] = i;
      }
  }
  // 并查集里寻根的过程
  int find(int u) {
      return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
  }
  
  // 判断 u 和 v是否找到同一个根
  bool isSame(int u, int v) {
      u = find(u);
      v = find(v);
      return u == v;
  }
  
  // 将v->u 这条边加入并查集
  void join(int u, int v) {
      u = find(u); // 寻找u的根
      v = find(v); // 寻找v的根
      if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
      father[v] = u;
  }
  • 路径压缩

    在每次寻根时,把这个节点直接放在根的下面,如图:

img

代码:

int find(int u) {
    return u == father[u] ? u : father[u] = find(father[u]);
 }

其中**father[u] = find(father[u])**就是路径压缩的过程

  • 复杂度
    • 空间复杂度:O(n)
    • 时间复杂度:在O(logn)与O(1)之间,且随着查询或者合并操作的增加,时间复杂度会越来越趋于O(1)(路径压缩)

(上述内容总结自代码随想录)

107.寻找存在的路径(卡码网)

题目描述

给定一个包含 n 个节点的无向图中,节点编号从 1 到 n (含 1 和 n )。

你的任务是判断是否有一条从节点 source 出发到节点 destination 的路径存在。

输入描述

第一行包含两个正整数 N 和 M,N 代表节点的个数,M 代表边的个数。

后续 M 行,每行两个正整数 s 和 t,代表从节点 s 与节点 t 之间有一条边。

最后一行包含两个正整数,代表起始节点 source 和目标节点 destination。

输出描述

输出一个整数,代表是否存在从节点 source 到节点 destination 的路径。如果存在,输出 1;否则,输出 0。

输入示例

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

输出示例

1

提示信息

img

数据范围:

1 <= M, N <= 100。](C:\Users\Lenovo\Pictures\Screenshots\屏幕截图 2024-10-12 112429.png)

在这里插入图片描述

#include <iostream>
#include <vector>
using namespace std;

int n;
vector<int> father(101,0);

void init()
{
    for(int i=1;i<=n;i++)
        father[i]=i;
}

int find(int u)
{
    return father[u]==u?u:father[u]=find(father[u]);
}

bool isSame(int u,int v)
{
    u=find(u);
    v=find(v);
    return u==v;
}

void join(int u,int v)
{
    u=find(u);
    v=find(v);
    if(u==v)
        return;
    else
        father[u]=v;
}

int main()
{
    int m,s,t,s1,s2;
    cin>>n>>m;
    init();
    for(int i=0;i<m;i++)
    {
        cin>>s>>t;
        join(s,t);
    }
    cin>>s1>>s2;
    if(isSame(s1,s2))
        cout<<1<<endl;
    else
        cout<<0<<endl;
}

原文地址:https://blog.csdn.net/2402_84438596/article/details/142872836

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!