题目链接:
传送门
题目描述:
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1个空格分隔。
输出格式:
按照"{ v1 v2 … vk }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。
输入样例:
8 6
0 7
0 1
2 0
4 1
2 4
3 5
输出样例:
{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }
样例示意图:
解题思路:
DFS和BFS相关知识点的考察,BFS的实现需要用到队列这一数据结构,为了代码简便,我们不妨调用c++库函数queue直接完成相关操作。
c参考代码:
#include <stdio.h>
#include <string.h>
#define maxsize 11
#define INF 0x3f3f3f3f
int n,e;
int G[11][11];
int visited[11];
typedef struct{
int ele[11];
int front,rear;
}Seq,*seq;
void init(seq Q)
{
Q->front=Q->rear=0;
}
int isEmpty(seq Q)
{
if(Q->front==Q->rear)
return 1;
else
return 0;
}
int isFull(seq Q)
{
if((Q->rear+1)%maxsize==Q->front)
return 1;
else
return 0;
}
int push(seq Q,int x)
{
if(isFull(Q)==1)
return 0;
else
{
Q->rear=(Q->rear+1)%maxsize;
Q->ele[Q->rear]=x;
return 1;
}
}
int pop(seq Q)
{
if(isEmpty(Q)==1)
return 0;
else
{
Q->front=(Q->front+1)%maxsize;
return 1;
}
}
int getFront(seq Q)
{
if(isEmpty(Q)==1)
return 0;
else
return Q->ele[Q->front+1];
}
void DFS(int id)
{
visited[id]=1;
printf(" %d",id);
int i;
for(i=0;i<n;i++)
{
if(G[id][i]==1&&visited[i]==0)
DFS(i);
}
}
void BFS(int id)
{
visited[id]=1;
Seq Q;
init(&Q);
push(&Q,id);
int i;
while(!isEmpty(&Q))
{
int temp=getFront(&Q);
pop(&Q);
printf(" %d",temp);
for(i=0;i<n;i++)
{
if(G[i][temp]==1&&visited[i]==0)
{
visited[i]=1;
push(&Q,i);
}
}
}
}
int main()
{
int i,x,y;
scanf("%d%d",&n,&e);
memset(G,INF,sizeof(G));
memset(visited,0,sizeof(visited));
for(i=0;i<e;i++)
{
scanf("%d%d",&x,&y);
G[x][y]=G[y][x]=1;
}
for(i=0;i<n;i++)
{
if(visited[i]==0)
{
printf("{");
DFS(i);
printf(" }\n");
}
}
memset(visited,0,sizeof(visited));
for(i=0;i<n;i++)
{
if(visited[i]==0)
{
printf("{");
BFS(i);
printf(" }\n");
}
}
return 0;
}
c++参考代码:
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#define MAX 11
#define INF 0x3f3f3f3f
using namespace std;
int n,e;
int visited[MAX];
int map[MAX][MAX];
void DFS(int id)
{
visited[id]=1;
printf(" %d",id);
for(int i=0;i<n;i++)
{
if(map[i][id]==1&&visited[i]==0)
DFS(i);
}
}
void BFS(int id)
{
visited[id]=1;
queue<int>Q;
Q.push(id);
while(!Q.empty())
{
int temp=Q.front();
Q.pop();
printf(" %d",temp);
for(int i=0;i<n;i++)
{
if(map[i][temp]==1&&visited[i]==0)
{
visited[i]=1;
Q.push(i);
}
}
}
}
int main()
{
int i,x,y;
cin>>n>>e;
memset(map,INF,sizeof(map));
memset(visited,0,sizeof(visited));
for(i=0;i<e;i++)
{
scanf("%d%d",&x,&y);
map[x][y]=map[y][x]=1;
}
for(i=0;i<n;i++)
{
if(visited[i]==0)
{
printf("{");
DFS(i);
printf(" }\n");
}
}
memset(visited,0,sizeof(visited));
for(i=0;i<n;i++)
{
if(visited[i]==0)
{
printf("{");
BFS(i);
printf(" }\n");
}
}
return 0;
}
参考资料:
传送门
不难发现,涉及到BFS的题目用c++调用库函数queue,可以省去很多代码,美观的同时也不容易出错。