秋招每日一题T23——连通图

给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。输入包含若干组数据。每组数据第一行包含两个整数 n 和 m,表示无向图的点和边数。接下来 m 行,每行包含两个整数 x,y,表示点 x 和点 y 相连。点的编号从 1 到 n。图中可能存在重边和自环。每组数据输出一行,一个结果,如果所有顶点都是连通的,输出 YES,否则输出 NO。输入最多包含 10 组数据。...
摘要由CSDN通过智能技术生成

题目描述

给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。

输入格式
输入包含若干组数据。

每组数据第一行包含两个整数 n 和 m,表示无向图的点和边数。

接下来 m 行,每行包含两个整数 x,y,表示点 x 和点 y 相连。

点的编号从 1 到 n。

图中可能存在重边和自环。

输出格式
每组数据输出一行,一个结果,如果所有顶点都是连通的,输出 YES,否则输出 NO。

数据范围
输入最多包含 10 组数据。
1≤n≤1000,
1≤m≤5000,
1≤x,y≤n
在这里插入图片描述

思路

①可以使用搜索解,当然这里使用并查集来解更快,这是一个裸的并查集模板。
②并查集的模板已经刻进骨髓里了,但是还有一些细节需要注意,即如何判断是否为连通图。
③判断方法是为每个点设一个点集个数,初始一定是每个点自己是一个,随着并查集集合的合并,连通图点集的数量会增加。
④最后找第一个点的父亲所在的集合中点的数量是否为n,即可判断是否为连通图。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1005
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是两种求连通最小生成树的算法: 1. 克鲁斯卡尔(Kruskal)算法 Kruskal算法是一种基于贪心思想的算法,它的基本思路是将所有边按照权值从小到大排序,然后依次加入到生成树中,如果加入该边后会形成环,则不加入该边。直到加入n-1条边为止,此时生成的树就是最小生成树。 ```python def find(parent, i): if parent[i] == i: return i return find(parent, parent[i]) def union(parent, rank, x, y): xroot = find(parent, x) yroot = find(parent, y) if rank[xroot] < rank[yroot]: parent[xroot] = yroot elif rank[xroot] > rank[yroot]: parent[yroot] = xroot else: parent[yroot] = xroot rank[xroot] += 1 def kruskal(graph): result = [] i = 0 e = 0 graph = sorted(graph, key=lambda item: item[2]) parent = [] rank = [] for node in range(len(graph)): parent.append(node) rank.append(0) while e < len(graph) - 1: u, v, w = graph[i] i = i + 1 x = find(parent, u) y = find(parent, v) if x != y: e = e + 1 result.append([u, v, w]) union(parent, rank, x, y) return result ``` 2. 普里姆(Prim)算法 Prim算法也是一种基于贪心思想的算法,它的基本思路是从一个点开始,每次选择一个与当前生成树相邻的权值最小的点加入到生成树中,直到加入n-1个点为止,此时生成的树就是最小生成树。 ```python import sys class Graph(): def __init__(self, vertices): self.V = vertices self.graph = [[0 for column in range(vertices)] for row in range(vertices)] def printMST(self, parent): print("Edge \tWeight") for i in range(1, self.V): print(parent[i], "-", i, "\t", self.graph[i][parent[i]]) def minKey(self, key, mstSet): min = sys.maxsize for v in range(self.V): if key[v] < min and mstSet[v] == False: min = key[v] min_index = v return min_index def primMST(self): key = [sys.maxsize] * self.V parent = [None] * self.V key[0] = 0 mstSet = [False] * self.V parent[0] = -1 for cout in range(self.V): u = self.minKey(key, mstSet) mstSet[u] = True for v in range(self.V): if self.graph[u][v] > 0 and mstSet[v] == False and key[v] > self.graph[u][v]: key[v] = self.graph[u][v] parent[v] = u return self.printMST(parent) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值