检测是否为连通图(深度优先遍历算法)

(一)九度上一个练习题

题目描述:

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

输入:

    每组数据的第一行是两个整数 n 和 m(0<=n<=1000)。n 表示图的顶点数目,m 表示图中边的数目。如果 n 为 0 表示输入结束。随后有 m 行数据,每行有两个值 x 和 y(0<x, y <=n),表示顶点 x 和 y 相连,顶点的编号从 1 开始计算。输入不保证这些边是否重复。

输出:

    对于每组输入数据,如果所有顶点都是连通的,输出”YES”,否则输出”NO”。

样例输入:
4 3
1 2
2 3
3 2
3 2
1 2
2 3
0 0
样例输出:
NO
YES

(二)判断图是否是连通的,可以通过深度优先遍历的方法判断。具体实现为:在图中选定任一一个顶点,对该顶点进行深度优先遍历,如果在这个遍历过程中所有的顶点都被遍历到,则该图为连通;反之,若存在没有被遍历到的顶点,则说明该图是非连通的。实现代码如下(针对无向图,使用邻接表结构):

#include <iostream>
#include <string.h>

using namespace std;

#define MAX_NODE 1000

typedef struct ArcNode
{
	int adjvex;//弧指向的节点的值(点的标号)
	ArcNode* next;//指向下一条弧
	ArcNode(int value)
	{
		adjvex = value;
		next = NULL;
	}
};//邻接表节点

typedef struct
{
	int vexdata; //头节点的标号
	struct ArcNode* firstarc;//第一个邻接表节点的地址
}VexNode, AdjList[MAX_NODE];//头结点

typedef struct
{
	AdjList vexNodes;
	int vexNum;
	int arcNum;//当前节点数目和弧数
}GraphWithAL;//邻接表表示的图

//检测要输入的边是否已经存在,针对无向图
bool CheckArcIsExist(GraphWithAL* G, int v1, int v2)
{
	ArcNode* temp = G->vexNodes[v1-1].firstarc;
	while(temp!=NULL)
	{
		if(temp->adjvex == v2)
			return true;
		temp = temp->next;
	}
	return false;
}

//创建图,vexNum代表顶点的个数,arcNum代表边的个数,isUnDirected代表的是 是否是无向图
void CreateGraph(GraphWithAL* G, int vexNum, int arcNum, bool isUnDirected)
{
	memset(G, 0 ,sizeof(GraphWithAL));
	//初始化头结点
	int i = 0;
	for(i=0; i<vexNum; ++i)
	{
		G->vexNum = vexNum;
		G->vexNodes[i].firstarc = NULL;
		G->vexNodes[i].vexdata = i+1;//从1开始计算顶点
	}
	//初始化边
	for(i=0; i<arcNum; ++i)
	{
		//输入边的顶点和尾点
		int v1, v2;
		cin>>v1>>v2;
		if(CheckArcIsExist(G, v1, v2))
			continue;
		ArcNode* arcNode = new ArcNode(v2);
		//还需要检验边是否已经存在,这里没有检验
		arcNode->next = G->vexNodes[v1-1].firstarc;
		G->vexNodes[v1-1].firstarc = arcNode;
		G->arcNum++;
		if(isUnDirected)
		{
			ArcNode* arcNode = new ArcNode(v1);
			//还需要检验边是否已经存在,这里没有检验
			arcNode->next = G->vexNodes[v2-1].firstarc;
			G->vexNodes[v2-1].firstarc = arcNode;
		}
	}
}

//对第vex个顶点递归的做深度优先遍历, 若遍历到该顶点则将visit数组中对应的值置为true
void DFS(GraphWithAL* G, int vex, bool* visit)
{
	//cout<<vex<<endl;
	visit[vex-1] = true;
	ArcNode* temp = G->vexNodes[vex-1].firstarc;
	if(temp == NULL)
	{
		//cout<<vex<<"->null"<<endl;
		return ;
	}
	while(temp != NULL)
	{
		if(!visit[temp->adjvex-1])
		{
			//cout<<vex<<"->"<<temp->adjvex<<endl;
			visit[temp->adjvex-1] = true;
			DFS(G, temp->adjvex, visit);
		}
		temp = temp->next;
	}
}
//深度优先遍历 图
void DFS_Visit(GraphWithAL* G)
{
	bool* visit = new bool[G->vexNum];
	memset(visit, 0, G->vexNum);
	int i=0;
	for(i=0; i<G->vexNum; ++i)
	{
		if(!visit[i])
		   DFS(G, i+1, visit);
	}
}
//检测图是否是连通的
bool CheckGraphIsConnected(GraphWithAL* G)
{  
   bool* visit = new bool[G->vexNum];
   memset(visit, 0, G->vexNum);
   DFS(G, 1, visit);
   int i=0;
   for(i=0; i<G.vexNum; ++i)
   {
	if(!visit[i])
           return true; 
    }
   return false;
} 
int main()
{
	GraphWithAL G;
	int n, m;
	while(cin>>n>>m)
	{
		if(n==0)
			break;
		CreateGraph(&G, n, m, true);
		//DFS_Visit(&G);
		//检测图是否连通
		bool flag = CheckGraphIsConnected(&G);
		if(flag)
			cout<<"NO"<<endl;
		else
			cout<<"YES"<<endl;
	}
  return 0;
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/cscmaker/article/details/8146897
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞