@算法学习

两种方法

  • DFS遍历法
  • 并查集法

1. DFS遍历计算连通块

先上代码:

#include <stdio.h>
#include <vector>using namespace std;const int maxn = 100010;
vector<int> G[maxn]; // 邻接表存储图bool vis[maxn] = {false}; // 标记是否访问void dfs(int v)
{vis[v] = true;for(int i = 0; i < G[v].size(); i++){if(vis[G[v][i]] == false){dfs(G[v][i]); // 如果该顶点未访问,深度遍历之}}
}int main()
{int n, a, b;scanf("%d", &n);for(int i = 1; i < n; i++) // n - 1条边{scanf("%d%d", &a, &b);G[a].push_back(b);G[b].push_back(a);}int block = 0;// 枚举所有顶点for(int i = 1; i <= n; i++){if(vis[i] == false){dfs(i);block++;}}printf("%d\n",block );
}Input :
5
1 2
1 3
1 4
2 5
Output:
1
Input:
5
1 3
1 4
2 5
3 4
Output:
2

注意到这里的dfs函数也没有人为控制递归边界;

dfs函数的目的就是为了标记单连通块中的所有结点,即令vis[v] = true;

在外围枚举所有顶点时,dfs一个顶点能把该块的所有顶点都“染色”为已经访问,通过控制语句,只有没访问过的才能进行dfs,那么一块只能有一个进来,所以可以进行计数。

2. 并查集法计算块数

#include <stdio.h>
#include <vector>using namespace std;const int maxn = 100010;
vector<int> G[maxn]; // 邻接表存储图bool isRoot[maxn] = {false}; // 标记是否访问
int pre[maxn];
int Find(int x)
{int r = x;while(x != pre[x]){x = pre[x];}// 路径压缩:此时x已经是老大int j;while(r != pre[r]){j = r;r = pre[r];pre[j] = x;}return x;
}void Union(int a, int b)
{int preA = Find(a);int preB = Find(b);if(preA != preB){pre[preA] = preB;}
}int calculateBlockNum(int n)
{int block = 0;for(int i = 1; i <= n; i++) // 枚举所有顶点{isRoot[Find(i)] = true;// 这样同样的数字只计算一次}for(int i = 1; i <= n; i++){block += isRoot[i]; //true当1用,false当0用}return block;
}void init(int n)
{for(int i = 1; i <= n; i++){pre[i] = i;}
}int main()
{int n, a, b;scanf("%d", &n);init(n); // 很重要很重要!for(int i = 1; i < n; i++) // n - 1条边{scanf("%d%d", &a, &b);G[a].push_back(b);G[b].push_back(a);Union(a,b); // 合并顶点a,b所在的集合}int block = calculateBlockNum(n);printf("%d\n",block);
}Input :
5
1 2
1 3
1 4
2 5
Output:
1
Input:
5
1 3
1 4
2 5
3 4
Output:
2

这个也很好理解,用这个代码数会稍微多一些,但是并查集的通用性值得好好学习。

在输入边的两个顶点时就可以开始进行合并+路径压缩,这样统计pre数组中的元素有多少个不同值即可,为了统计,自然用到标记数组,这里不用统计每个块中的元素数目,所以用布尔型的数组即可。

统计图的连通块的个数的两种方法相关推荐

  1. (C++)求Fibonacci数列的第n个数的两种方法

    方法一 #include<cstdio> #include<cmath>int main(){int n;scanf("%d",&n);if(n== ...

  2. 计算一个连通分量中节点的个数的两种方法

    POJ 1611 The Suspects(并查集) 2014年03月11日 11:17:28 阅读数:1027 POJ 1611 The Suspects(并查集) http://poj.org/p ...

  3. 图中连通块的个数:并查集

    图的连通性问题 在地图上有若干城镇(点),已知所有有道路直接相连的城镇对.要解决整幅图的连通性问题.比如,随意给你两个点,让你判断它们是否连通:或者问你整幅图一共有几个连通块,也就是被分成了几个互相独 ...

  4. python统计中文字符的个数_python统计中文字符数量的两种方法

    方法一: def str_count(str): '''找出字符串中的中英文.空格.数字.标点符号个数''' count_en = count_dg = count_sp = count_zh = c ...

  5. 求两个数的最小公倍数; 两种方法

    个人博客网站:https://www.liuzhi.org.cn/ //#include<stdio.h> //求两个数的最小公倍数: 两种方法 //1 //int main() //{ ...

  6. python统计汉字个数是_python统计中文字符数量的两种方法

    方法一: def str_count(str): '''找出字符串中的中英文.空格.数字.标点符号个数''' count_en = count_dg = count_sp = count_zh = c ...

  7. python比较两个数的和_Python中的is和==比较两个对象的两种方法

    Python中的is和==比较两个对象的两种方法 在Python中有两种方式比较两个对象是否相等,分别是is和==,两者之间是不同的 ==比较的是值(如同java中的equals方法) is比较的是引 ...

  8. c#二叉树 取叶子节点个数_两种类似但是原理不同的算法求二叉树的所有叶子节点和...

    技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后到中级难度,最后到hard难度全部完. 目前我选择C语言,Python和Java作为实现语言,因为这三种 ...

  9. VBA实现两种方法生成任意概率分布的随机数

    引子 一把武器的品质有分为最下级.下级.中级.上级.最上级五档,我希望在击杀一只怪物的时候,这把武器的掉率:最下级>下级>中级>上级>最上级,问如何设计满足上面的需求? 在游戏 ...

最新文章

  1. Testlink使用介绍
  2. 在ASP.NET Core上实施每个租户策略的数据库
  3. 12.15模拟:总结
  4. Oracle ADF移动世界! 你好!
  5. 【bzoj4399】魔法少女LJJ 并查集+权值线段树合并
  6. python计算股票趋势_通过机器学习的线性回归算法预测股票走势(用Python实现)...
  7. 【Faster RCNN detectron2】detectron2实现Faster RCNN目标检测
  8. linux 等待进程,Linux 进程等待队列
  9. Nginx配置单项SSL以及双向SSL
  10. 【转】两厢车与三厢车安全性哪个好?
  11. 替罪羊树+3369 【模板】普通平衡树
  12. 使用LoadBalancerClient就行服务消费
  13. php对表中的字段自选排序,Mysql应用MySQL 按指定字段自定义列表排序的实现
  14. Python中终端彩色打印输出
  15. mysql pxc集群介绍_MySQL中PXC集群的介绍
  16. 杭州银行面试题【杭州多测师】【杭州多测师_王sir】
  17. Java widget xui_XUI使用总结
  18. 如何在 EXCEL 2003 插入的方框内打对勾,复选框
  19. 中国大学MOOC所有课程信息爬虫(课程ID、学校简称、课程名字、教师、学校全称、学生人数、学生人数、评价人数、平均评价)
  20. 关于程序代码的时间复杂度

热门文章

  1. ubuntu14.04+CUDA7.5+cuDNN+caffe的超详细完整配置
  2. tensorflow随笔——深度学习中GPU型号对比
  3. 【C++笔记】运算符重载
  4. Linux下gcc/g++、make和cmake的区别
  5. linux session 设置时间设置,设置linux系统history相关变量,命令时间、保存history条数,多session共享history...
  6. OpenCV图像处理(13)——指定区域截取和指定区域复制
  7. linux安装或卸载mysql5,Linux环境下卸载、安装及配置MySQL5.1
  8. vbs获取程序窗体句柄_VBS调用windows api函数(postmessage)实现后台发送按键脚本...
  9. matlab 传递函数 画出频率响应,MATLAB环境下频率响应曲线的绘制方法
  10. confluence启动不起来_“一键启动”只能点火?还有这5个“隐藏”功能,你都知道吗?...