数据结构:图--列出连通集

108 阅读2分钟

本文已参加[新人创作礼]活动,一起开启掘金创作之路。

 ​编辑

        当时做题的时候,考虑了解决方法。如果要用父子关系来解决这个问题的话,一个父亲有多个儿子,而且不清楚谁为父亲,谁为儿子。我就让序号小的作为父亲,用visit数组来判断他是不是被访问过,如果访问过,就跳过。而且,因为加入的顺序不确定,还涉及给儿子排序,十分麻烦,也只解决了深度搜索,至于广搜就一筹莫展了。 

        在网上查阅资料,看到了邻接矩阵的方法,觉得非常实用。我觉得写的很好,故列于左。供有缘人更好的学习。以下也算是我自己的学习巩固以求加深理解。

列出联通集

        

         邻接矩阵:(百度,此处只说无向图)

         L[v][u]=1;v代表起始,u代表终点,L代表u-v的权值。

                1、对角线上都为0,数据关于对角线对称

                2、出度等于入度,且等于行或列不为0元素的个数

                3、存储邻接矩阵需要n*n个空间,但因为高度对称,所以只需要一个上三角或者下三角的空间即可 (n-1)*n/2;

​编辑

 (图丑勿喷)

         为什么要用邻接矩阵呢??因为这样对于每一个点来说,我的任务只需找到与我相邻为1的节点,那么操作的核心就是如何遍历这些点。

        题目给出从编号最小的开始,那么我们可以从0开始遍历,先找到他的邻接点,在推而广之,找到他的邻接点的邻接点,这样我们就可以遍历出所有有路的节点了。那么对于访问过的节点,为了防止重复访问,导致程序崩溃,我们设置一个visit[]数组,用来判断是否遍历过。

DFS

        

void dfs(int id)
{	
	cout<<id<<" ";
	visit[id]=1;
	for(int i=0;i<n;i++)
	{
		if(L[id][i]==1&&!visit[i])//如果与id之间有路,并且没有访问过该节点 
		{
			visit[i]=1;
			dfs(i);
		}
	}
}

先找到第一个节点,然后找到他的邻接点,在找的邻接点的邻接点。。。。。

BFS

对于广搜来讲,我们需要先把某点所有的邻接点输出,再去找邻接点的邻接点。那么如何再找到我的第一个邻接点呢?所以我们需要先把邻接点存起来,用数组或者动态数组,都会涉及到下标的问题,不好操作。所以我们选择用队列,这样当我们查找邻接点的邻接点时,能保证邻接点还是按照我们访问的顺序。

void bfs(int id)//我只负责把与我距离为一的节点输出来,至于接下来的交给我的结点 
{
	queue<int>que;
	que.push(id);
	while(!que.empty())
	{
		int t=que.front();
		que.pop();
		for(int i=0;i<n;i++)
		{
			if(!visit[i]&&L[i][t]==1)
			{
				cout<<i<<" ";
				visit[i]=1;
				que.push(i);
			}
		}
	}
}

总代码:

#include <iostream>
#include <string.h>
#include <queue> 
using namespace std;
int n,m;
int L[205][205];
int visit[105];
void dfs(int id)
{	
	cout<<id<<" ";
	visit[id]=1;
	for(int i=0;i<n;i++)
	{
		if(L[id][i]==1&&!visit[i])//如果与id之间有路,并且没有访问过该节点 
		{
			visit[i]=1;
			dfs(i);
		}
	}
}
void bfs(int id)//我只负责把与我距离为一的节点输出来,至于接下来的交给我的结点 
{
	queue<int>que;
	que.push(id);
	while(!que.empty())
	{
		int t=que.front();
		que.pop();
		for(int i=0;i<n;i++)
		{
			if(!visit[i]&&L[i][t]==1)
			{
				cout<<i<<" ";
				visit[i]=1;
				que.push(i);
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		L[x][y]=1;
		L[y][x]=1;
	}
	for(int i=0;i<n;i++)
	{
		if(!visit[i])
		{
			cout<<"{ ";
			dfs(i);
			cout<<"}"<<endl;
		} 
		
	}
	memset(visit,0,sizeof(visit));
	for(int i=0;i<n;i++)
	{
		if(!visit[i])
		{
			cout<<"{ ";
			cout<<i<<" ";
			visit[i]=1;
			bfs(i);
			cout<<"}"<<endl;
		}
	}
} 

<--------------------前路茫茫,且安静的奋进-------------------->

<-------------务实之心强一分,则好名之心少一分------------>