题目
给定一个有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 }
运行结果
Case | Hint | Result | Run Time | Memory |
---|---|---|---|---|
0 | sample 两种顺序不同,也有相同,有未出现的单个顶点 | Accepted | 2 ms | 384 KB |
1 | 第1个是单独点,最大N | Accepted | 2 ms | 388 KB |
2 | N和E最小 | Accepted | 2 ms | 360 KB |
程序
#include<iostream>
using namespace std;
#define MaxVertexNum 10 //最大顶点数
typedef int Vertex;//用顶点下标表示顶点,为整型
typedef int WeightType;//边的权值为整型
/*边的定义*/
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1, V2;
};
typedef PtrToENode Edge;
/*图的定义*/
/*图用邻接数组表示:比无向图节省一半的空间*/
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;//顶点数
int Ne;//边数
WeightType G[MaxVertexNum][MaxVertexNum];//邻接矩阵的数组定义
};
typedef PtrToGNode MGraph;
/*队列链表的结点定义*/
struct Node{
Vertex v;
struct Node *Next;
};
/*队列的定义*/
struct QNode{
struct Node *Rear;//指向队尾结点
struct Node *Front;//指向队首结点
};
typedef struct QNode *Queue;
/*图中顶点的遍历状态数组,false表示未被遍历过*/
bool visited[MaxVertexNum];
MGraph BuildGraph();
MGraph CreateGraph(int N);
void InsertEdge(MGraph Graph, Edge e);
void DFSPrintListComponents(MGraph Graph);
void DFS(MGraph Graph, Vertex v);
void BFSPrintListComponents(MGraph Graph);
Queue initializeQueue();
void BFS(MGraph Graph, Vertex v);
void Enqueue(Vertex v, Queue Q);
bool IsEmpty(Queue Q);
Vertex Dequeue(Queue Q);
int main()
{
MGraph Graph;
/*根据输入构建邻接矩阵图*/
Graph = BuildGraph();
/*初始化结点遍历状态*/
for(int v=0; v<MaxVertexNum; v++)
visited[v] = false;
/*用DFS遍历图*/
DFSPrintListComponents(Graph);
/*清空结点遍历状态*/
for(int v=0; v<MaxVertexNum; v++)
visited[v] = false;
/*用BFS遍历图*/
BFSPrintListComponents(Graph);
return 0;
}
MGraph CreateGraph(int N)
{
MGraph Graph;
Graph = new GNode;
Graph->Nv = N;
Graph->Ne = 0;
/*当两个顶点未连接时,默认将边的权重设为0*/
for(int v=0; v<Graph->Nv; v++){
for(int w=0; w<Graph->Nv; w++)
Graph->G[v][w] = 0;
}
return Graph;
}
void InsertEdge(MGraph Graph, Edge e)
{
/*作为无向图,以下两个都要修改*/
Graph->G[e->V1][e->V2] = 1;
Graph->G[e->V2][e->V1] = 1;
}
MGraph BuildGraph()
{
int N, E;
MGraph Graph;
Edge e;
/*测试用例*/
/*
N = 8;
//初始有N个顶点但没有边的图
Graph = CreateGraph(N);
E = 6;
Graph->Ne = E;
//所有边
int AllEdge[6][2] = \
{ {0,7},
{0,1},
{2,0},
{4,1},
{2,4},
{3,5}};
if(Graph->Ne != 0){//图中有边
e = new ENode;
for(int i=0; i<Graph->Ne; i++){
e->V1 = AllEdge[i][0];
e->V2 = AllEdge[i][1];
InsertEdge(Graph, e);
}
}
*/
/*实际应用*/
cin >> N;//顶点总数
Graph = CreateGraph(N);//初始有N个顶点但没有边的图
cin >> E;//边的总数
Graph->Ne = E;
//根据输入构建图
if(Graph->Ne != 0){//图中有边
e = new ENode;
for(int i=0; i<Graph->Ne; i++){
cin >> e->V1;
cin >> e->V2;
InsertEdge(Graph, e);
}
}
return Graph;
}
void DFSPrintListComponents(MGraph Graph)
{
if(Graph->Nv != 0){/*图中有结点*/
for(int v=0; v<Graph->Nv; v++)
if(!visited[v]){/*该结点未被访问过*/
cout << "{ ";
DFS(Graph, v);
cout << "}\n";
}
}
}
void BFSPrintListComponents(MGraph Graph)
{
if(Graph->Nv != 0){/*图中有结点*/
for(int v=0; v<Graph->Nv; v++)
if(!visited[v]){/*该结点未被访问过*/
cout << "{ ";
BFS(Graph, v);
cout << "}\n";
}
}
}
void DFS(MGraph Graph, Vertex v)
{
visited[v] = true;
cout << v << " ";
for(int w=0; w<MaxVertexNum; w++){
if(Graph->G[v][w] > 0 && !visited[w]){
/*表明v和w有边连接,且w未被遍历过*/
DFS(Graph, w);
}
}
}
void BFS(MGraph Graph, Vertex v)
{
/*初始化队列*/
Queue Q;
Q = initializeQueue();
visited[v] = true;
cout << v << " ";
/*入队*/
Enqueue(v, Q);
while(!IsEmpty(Q)){
/*出队*/
v = Dequeue(Q);
for(Vertex w=0; w<MaxVertexNum; w++){
if(Graph->G[v][w] > 0 && !visited[w]){
//v和w有边,且w未被遍历过
visited[w] = true;
cout << w << " ";
Enqueue(w, Q);
}
}
}
}
Queue initializeQueue()
{
Queue Q;
Q = new QNode;
Q->Front = NULL;
Q->Rear = NULL;
return Q;
}
void Enqueue(Vertex v, Queue Q)
{
Node *NewNode;
NewNode = new Node;
NewNode->v = v;
NewNode->Next = NULL;
if(IsEmpty(Q)){
Q->Front = NewNode;
Q->Rear = NewNode;
}
else{
Q->Rear->Next = NewNode;
Q->Rear = NewNode;
}
}
Vertex Dequeue(Queue Q)
{
Vertex v;
Node *temp;
v = Q->Front->v;
temp = Q->Front;
Q->Front = Q->Front->Next;
delete temp;
return v;
}
bool IsEmpty(Queue Q)
{
return (Q->Front == NULL);
}