判断图连通的三种方法——dfs,bfs,并查集
Description
如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的。现在给定一张无向图,判断它是否是连通的。
Input
第一行有2个整数n和m(0 < n,m < 1000000), 接下来m行每行有2个整数u,v (1<=u,v<=n)表示u和v有边连接。
Output
如果无向图是连通的输出yes,否则输出no
Sample Input
4 6
1 2
2 3
1 3
4 1
2 4
4 3
Sample Output
yes
[图的遍历算法]
题目分析:判断图是否连通,可用dfs和bfs遍历图算法,注意点数目较多,又是稀疏图的话,最后使用邻接表的方法存储。另外推荐采用的是并查集的方法。初始化时将每个节点看作一个集合,则每给出一条边即把两个集合合并。最后遍历所有点,有几个集合便有几个连通分量,若只有一个集合说明图连通。并查集方法通常情况下时间效率较高,还能判断一个图是否有回路,在kruskal算法中也可以使用。
下分别给出三种方法的代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std; int set[]; int find(int x){ returnx==set[x]?x:(set[x]=find(set[x])); //递归查找集合的代表元素,含路径压缩。 } int main() { int n,m,i,x,y; scanf("%d%d",&n,&m); for(i=;i<;++i) //初始化个集合,数组值等于小标的点为根节点。 set[i]=i; for(i=;i<m;++i){ int a,b; scanf("%d%d",&a,&b); int fx=find(a),fy=find(b); set[fx]=fy; //合并有边相连的各个连通分量 } int cnt=; for(i=;i<=n;++i) //统计集合个数,即为连通分量个数,为一时,图联通。 if(set[i]==i) ++cnt; if(cnt==)
printf("yes\n");
else printf("no\n"); return ;
}
并查集
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm> using namespace std;
const int MAXN=;
vector<int> g[MAXN];
bool vis[MAXN];
int n,m;
void dfs(int s){ //递归深搜
vis[s]=true;
for(int i=;i<g[s].size();++i){
if(vis[g[s][i]]) g[s].erase(g[s].begin()+i);//删除图中已经遍历过的点,可提高遍历速度
else dfs(g[s][i]);
}
} bool judge(){ //判断是否所有点已被遍历过
for(int i=;i<=n;++i)
if(!vis[i])
return false;
return true;
} int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;++i) g[i].clear();
for(int i=;i<m;++i){
int a,b;
scanf("%d%d",&a,&b);
g[a].push_back(b); //无向图转化为有向图,正反两次存入连接表。
g[b].push_back(a);
}
memset(vis,false,sizeof(vis));
dfs();
if(judge())
printf("yes\n");
else printf("no\n");
}
return ;
}
DFS
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue> using namespace std;
const int MAXN=;
vector<int> g[MAXN];
bool vis[MAXN];
int n,m;
void bfs(int s){ //用队列广搜
queue<int> q;
q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
vis[x]=true;
for(int i=;i<g[x].size();++i){
if(vis[g[x][i]]) g[x].erase(g[x].begin()+i);//删除图中已经遍历过的点,可提高遍历速度
else q.push(g[x][i]);
}
}
} bool judge(){ //判断是否所有点已被遍历过
for(int i=;i<=n;++i)
if(!vis[i])
return false;
return true;
} int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;++i) g[i].clear();
for(int i=;i<m;++i){
int a,b;
scanf("%d%d",&a,&b);
g[a].push_back(b); //无向图转化为有向图,正反两次存入连接表。
g[b].push_back(a);
}
memset(vis,false,sizeof(vis));
bfs();
if(judge())
printf("yes\n");
else printf("no\n");
}
return ;
}
BFS
判断图连通的三种方法——dfs,bfs,并查集的更多相关文章
- C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?
C#中??和?分别是什么意思? 在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; ...
- vue自定义指令,比onerror更优雅的方式实现当图片加载失败时使用默认图,提供三种方法
首先,来看下效果图(演示一下图片正常加载与加载失败时的效果) 在线体验地址:https://hxkj.vip/demo/vueImgOnerror/ 一.常规方法解决 我们都知道,img标签支持one ...
- Jquery判断Checkbox是否选中三种方法
方法一:if ($("#checkbox-id")get(0).checked) { // do something} 方法二:if($('#checkbox-id').is ...
- perl 判断数组相等的三种方法
1.数组相等,数组成员相同,位置也相同 一般的如果判断@array1 等于 @array2 a.数组长度相同 $#array1=$#array2, 比较数组长度,不能使用length函数,length ...
- js如何判断一个对象是不是Array? 三种方法总有一种可以帮上忙
转载:http://www.nowamagic.net/librarys/veda/detail/1250 在开发中,我们经常需要判断某个对象是否为数组类型,在Js中检测对象类型的常见方法都有哪些呢? ...
- 像画笔一样慢慢画出Path的三种方法(补充第四种)
今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...
- (转)Java结束线程的三种方法
背景:面试过程中问到结束线程的方法和线程池shutdown shutdownnow区别以及底层的实现,当时答的并不好. Java结束线程的三种方法 线程属于一次性消耗品,在执行完run()方法之后线程 ...
- LwIP协议栈开发嵌入式网络的三种方法分析
LwIP协议栈开发嵌入式网络的三种方法分析 摘要 轻量级的TCP/IP协议栈LwIP,提供了三种应用程序设计方法,且很容易被移植到多任务的操作系统中.本文结合μC/OS-II这一实时操作系统,以 ...
- c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)
c#封装DBHelper类 public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...
随机推荐
- Fibonacci again and again HDU - 1848
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)=2; F(n)=F(n-1)+F(n-2)(n>=3); 所以,1, ...
- 工具类commons-io的Tailer用来监控文件
一.前言:在Linux下有使用tail命令 在Commons-io中也提供这种方法 二.他采用的是线程方式来监控文件内容的变化 1.Tailer类(采用线程的方式进行文件的内容变法) 2.Tailer ...
- Tomcat 在 Linux 下的自动启动脚本
很多服务都需要设置为开机自启动.将下面代码复制到 /etc/rc.d/init.d/tomcat ,然后执行 chkconfig –add tomcat chkconfig tomcat on 就可以 ...
- MySQL之索引(三)
聚簇索引 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式.具体的细节依赖于其实现方式,但InnoDB的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行.当表有聚簇索引时,它的数据行实 ...
- 03012_会话技术Cookie&Session
1.会话技术简介 (1)存储客户端的技术 网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户端是谁,所以需要会话技术识 ...
- CMD命令简介
cmd是command的缩写.即命令行 . 虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全.稳定,有的用户还在使用,所以一般Wind ...
- loj2092 「ZJOI2016」大森林
ref不是太懂-- #include <algorithm> #include <iostream> #include <cstring> #include < ...
- centOS6.6虚拟机启动后登陆界面无法显示
1.图一和图二对比就很明显发现,我的登陆界面不见了(突然断电导致不正常关机,造成图形界面桌面崩溃) 2.解决方法:启动按Ctrl+Alt+f2切换进命令行界面,root账号进入,重新下载图形界面
- PS教程超级合辑【800+集爆款课】
第1章 导读——推荐大家到网易云课堂学习购买(本博文仅为个人学习笔记)https://study.163.com/course/courseMain.htm?courseId=1442008& ...
- Leetcode 558.四叉树交集
四叉树交集 四叉树是一种树数据,其中每个结点恰好有四个子结点:topLeft.topRight.bottomLeft 和 bottomRight.四叉树通常被用来划分一个二维空间,递归地将其细分为四个 ...