首页 > 其他分享 >统计连通分量个数

统计连通分量个数

时间:2024-12-10 11:32:36浏览次数:5  
标签:连通 int graph 个数 分量 节点 size

求连通分量

 图的连通性

题目描述
给定一个n个节点m条边的无向图G,节点编号从1到n,保证图中没有重边和自环。

现在,你要统计G的连通分量数目C,以及每个连通分量的大小(节点数目)。

输入描述
第1行包含两个整数n,m (2≤n≤10 
4
 ,1≤m≤2×10 
5
 ),表示节点个数和边数。
接下来m行,每行包含两个整数u,v (1≤u,v≤n),表示一条连接节点u和节点v的无向边。

输出描述
第一行,一个数字,表示图G的连通分量数目C。
第二行,包含C个整数,表示每个连通分量的大小,按照升序排列。

输入样例1
9 11
3 6
4 6
3 5
3 4
1 4
1 3
6 5
4 5
7 2
5 1
1 6
​
输出样例1
4
1 1 2 5
​
随机测试数据
子任务	平均占比	约束
子任务0	20%	n≤10,m≤20
子任务1	20%	n≤100,m≤200,且连通分量数目不超过2个
子任务2	60%	无约束
提示
在C++中,可以使用std::sort()和对整数数组按照升序或降序排列。

#include <algorithm>
#include <vector>

int main() {
  std::vector<int> arr;
  // ...
  std::sort(arr.begin(), arr.end()); // 升序排序
  std::sort(arr.begin(), arr.end(), greater<int>{}); // 降序排序
}
​

方案:

1. 初始化:创建一个数组或 visited 数组,记录每个节点是否被访问过。

2. 遍历每个顶点:对于每一个未访问的顶点,启动一个深度优先搜索(DFS)或者广度优先搜索(BFS),将该连通分量中的所有节点标记为已访问。

3. 计数连通分量:每当从一个未访问的顶点开始进行 DFS/BFS 时,说明找到一个新的连通分量,计数器加一。
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;

vector<bool> visit;
vector<int> res;

class Graph{
public:
    int vertexNum;
    vector<vector<int>> adj;
    Graph(int n) : vertexNum(n), adj(n + 1){
    }
    void addEdge(int u, int v){
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
};
void dfs(int startVertex, int& _size, Graph& graph){
    vector<int> nowList = graph.adj[startVertex];
    for(size_t i = 0; i < nowList.size(); i++){
        if(!visit[nowList[i]]){
            visit[nowList[i]] = 1;
            _size++;
            dfs(nowList[i], _size, graph);
        }
    }
}

int main(){
    int n, m;
    cin >> n >> m;
    Graph graph(n);
    visit.resize(n + 1);
    while(m--){
        int u, v;
        cin >> u >> v;
        graph.addEdge(u, v);
    }

    for(int i = 1; i <= n; i++){
        if(!visit[i]){
            visit[i] = 1;
            int _size = 1;
            dfs(i, _size, graph);
            res.push_back(_size);
        }
    }
    cout << res.size() << endl;
    sort(res.begin(), res.end());
    for(size_t i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    return 0;
}

标签:连通,int,graph,个数,分量,节点,size
From: https://blog.csdn.net/2301_81373791/article/details/144367989

相关文章

  • 使用js写一个方法生成0000-9999一万个数字(4位数)
    functiongenerateFourDigitNumbers(){constnumbers=[];for(leti=0;i<=9999;i++){//UsepadStarttoensureeachnumberis4digitslongconstnumberString=i.toString().padStart(4,'0');numbers.push(numberString);......
  • 【唐叔学算法】第八天:并查集-图论连通性的大杀器
    你是否曾为如何高效地解决图论中的连通性问题而烦恼?并查集算法,就像一张无形的网,能帮你轻松连接所有节点。今天,就让我们一起揭开并查集算法的神秘面纱,探索它在Java编程中的应用。并查集是什么?并查集(Union-Find)是一种数据结构,用于处理一些不交集的合并及查询问题。它支持两......
  • 逆序对个数
    题目一个数列,如果左边的数大,右边的数小,则称这两个数为一个逆序对。求出一个数列中右多少个逆序对。解法1暴力遍历所有可能的数对。packagecom.company;publicclassTest17{publicstaticvoidmain(String[]args){int[]arr={1 ,4 ,9, 6 ,2, 8, 7 ......
  • 当Doris遇上福尔摩斯:一个数据库优化器的推理日记
    当Doris遇上福尔摩斯:一个数据库优化器的推理日记Doris智能化SQL优化引擎智能优化背后的故事作为一名数据分析师,你一定遇到过这样的场景:写了一个看似简单的SQL查询,信心满满地点击执行,然后…不知不觉喝完三杯咖啡,查询还在默默转圈圈。"这也太慢了吧!"小王抓狂地盯着屏......
  • #C01L06P01. C01.L06.复合语句、数值交换、三个数的最值与排序.复合语句
    例1:运行下列程序,输入5,观察运行结果并思考程序是怎样运行的。#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn,a=0,b=0,c=0; cin>>n; if(n<0) a=a+2; b=b+2; c=c+2; cout<<a<<""<<b<<""<<c; re......
  • 有 n 个整数,使前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m个数
    题目描述        有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面的m个数,见下图,写一个函数实现该功能。代码实现voidMove(int*arr,intn,intm){if(m<=0||m>=n)return;//创建m个长度的int数组int*brr=(int*)malloc(m*si......
  • 数组中出现次数超过一半的数字整型数组有一个数字出现的次数超过总数的一半,请找出该
    题目描述        数组中出现次数超过一半的数字整型数组有一个数字出现的次数超过总数的一半,请找出该数字,例如长度为9的数组{1,2,3,2,4,2,5,2,2}。由于2出现的次数是5次,超过一半,所以结果为2。代码实现算法1:先排序,然后中间值就是要找的数字 intCmp......
  • SQL面试题——腾讯SQL面试题 占据好友封面个数
    腾讯SQL面试题占据好友封面个数有两个表,朋友关系表user_friend,用户步数表user_steps。朋友关系表包含两个字段,用户id,用户好友的id;用户步数表包含两个字段,用户id,用户的步数查询:占据多少个好友的封面(在好友的列表中排行第一,且必须超过好友的步数)--好友关系表+-------+-......
  • 将一个数组逆序输出。-多语言
    目录C语言实现方法1: 交换元素方法2: 使用辅助数组方法3:使用递归 方法4:使用标准库函数(C99及以上)总结Python实现方法1: 交换元素方法2:使用切片 方法3:使用reversed()函数方法4:使用list.reverse()方法方法5:使用for循环和append()......
  • 2024-12-02:划分数组得到最小的值之和。用go语言,你有两个数组,nums 和 andValues,它们的
    2024-12-02:划分数组得到最小的值之和。用go语言,你有两个数组,nums和andValues,它们的长度分别为n和m。定义数组的“值”为其最后一个元素。你的任务是将nums划分为m个不重叠的连续子数组。对于第i个子数组[li,ri],该子数组的所有元素通过按位与运算后,结果必须等......