7-22 List Components

题目如下:

7-22 List Components (25 分)

For a given undirected graph with N vertices and E edges, please list all the connected components by both DFS (Depth First Search) and BFS (Breadth First Search). Assume that all the vertices are numbered from 0 to N-1. While searching, assume that we always start from the vertex with the smallest index, and visit its adjacent vertices in ascending order of their indices.

Input Specification:

Each input file contains one test case. For each case, the first line gives two integers N (0<N≤10) and E, which are the number of vertices and the number of edges, respectively. Then E lines follow, each described an edge by giving the two ends. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in each line a connected component in the format { v​1​​ v​2​​ ... v​k​​ }. First print the result obtained by DFS, then by BFS.

Sample Input:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

Sample Output:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

题目规定的输入的顶点数不超过10,因此可以用图的邻接矩阵存储信息;边有可能平行,因此用a[i][j]!=0来判断是否存在边,而非用a[i][j]==1进行判断;主函数代码如下:

int main()
{
	//freopen("in.txt","r",stdin);
	cin>>N>>E;
	for(int i=0;i<E;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		a[x][y]=a[y][x]+=1;
	}
	FS(DFS);
	FS(BFS);
	return 0;
} 
#endif

在FS函数中,其参数格式为void (*FS)(int),缺一不可,在循环中,每一次一趟,分两部分,先遍历后输出。图可能不是连通图,因此需要用大括号(按照输出格式要求)将每一趟遍历结果括起来,最好用队列来存放,这样思路比较清晰,格式的控制也比较灵活(体现在if(!q,empty())上);注意要及时清空v[]要及时清空(清为0),因为v是用来记录是否遍历过。代码如下:

void FS(void (*FS)(int))
{
	memset(v,0,sizeof(v));
	for(int i=0;i<N;i++)
	{
		if(v[i]==0)//遍历的前提是未遍历过
		{
			FS(i);
			cout<<"{ ";
			while(!q.empty())
			{
				printf("%d ",q.front());
				q.pop();
			}
			cout<<"}\n";
		}
	}
}

在DFS函数中,用递归实现较为清晰,每碰到一个未遍历的顶点,先不做标记(这一点很重要),也不入队,直接进入下一层,这是为了避免中断继续深入遍历,并且只在下一层标记和入队。代码如下:

void DFS(int x)
{
	v[x]=1;
	q.push(x);
	for(int i=0;i<N;i++)
	{
		if(v[i]==0&&a[x][i])//邻接顶点
		{
			DFS(i);
		}
	}
}

在BFS函数中,用队列实现较为直观,知道队列为空才跳出循环,每趟均需要出队,有时会进队,因此不会陷入死循环的。代码如下:

void BFS(int x)
{
	v[x]=1;
	q.push(x);
	queue<int> qq;
	qq.push(x);
	while(!qq.empty())
	{
		int y=qq.front();
		qq.pop();
		for(int i=0;i<N;i++)
		{
			if(v[i]==0&&a[y][i])//邻接顶点
			{
				v[i]=1;
				qq.push(i);
				q.push(i);
			}
		}
	}
}

总代码如下:

#if 1 
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <deque>
#include <map>
#include <set>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime> 
using namespace std;
int a[15][15],N,v[15],E;
queue<int> q;
void DFS(int x)
{
	v[x]=1;
	q.push(x);
	for(int i=0;i<N;i++)
	{
		if(v[i]==0&&a[x][i])
		{
			DFS(i);
		}
	}
}
void BFS(int x)
{
	queue<int> qq;
	v[x]=1;
	q.push(x);
	qq.push(x);
	while(!qq.empty())
	{
		int y=qq.front();
		qq.pop();
		for(int i=0;i<N;i++)
		{
			if(v[i]==0&&a[y][i])
			{
				v[i]=1;
				qq.push(i);
				q.push(i);
			}
		}
	}
}
void FS(void (*FS)(int))
{
        memset(v,0,sizeof(v));
	for(int i=0;i<N;i++)
	{
		if(v[i]==0)
		{
			FS(i);
			cout<<"{ ";
			while(!q.empty())
			{
				printf("%d ",q.front());
				q.pop();
			}
			cout<<"}\n";
		}
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	cin>>N>>E;
	for(int i=0;i<E;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		a[x][y]=a[y][x]=1;
	}
	FS(DFS);
	FS(BFS);
	return 0;
} 
#endif

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值