以邻接矩阵作存储结构,编写程序对给定的无向图(图中包含n个顶点,编号为0至n-1
)进行深度优先遍历,并在遍历的过程中计算图G的连通分量个数及边的数目。
本题限定在遍历过程中,如果同时出现多个待访问的顶点,则优先选择编号最小
的一个进行访问,以顶点0
为遍历起点。
邻接矩阵的类型描述
#define MaxVexNum 20 //最大顶点数目
typedef struct
{ int arcs[MaxVexNum][MaxVexNum];
int vexnum, arcnum;
}AMGraph;
输入格式:
第一行输入图的顶点数
和边数
。
接下来每行代表一条边,输入边依附的两个顶点的编号
。各边输入先后次序无要求。
输出格式
输出分三行
- 第一行 深度优先遍历序列。序列中每个顶点编号后跟一个空格。
- 第二行 连通分量个数
- 第三行 边数
对于下面给出的无向图G
输入样例:
9 8
0 1
0 2
1 3
3 4
2 5
2 6
5 6
7 8
输出样例:
0 1 3 4 2 5 6 7 8
2
8
#include <stdio.h>
#define MaxVexNum 20
typedef struct
{
int arcs[MaxVexNum][MaxVexNum];
int vexnum, arcnum;
} AMGraph;
int visited[MaxVexNum]; // 记录顶点是否被访问过
void DFS(AMGraph *G, int v)
{
printf("%d ", v);
visited[v] = 1; // 标记该顶点已经被访问
for (int i = 0; i < G->vexnum; ++i)
{
if (G->arcs[v][i] && !visited[i])
{
DFS(G, i);
}
}
}
int main()
{
AMGraph G;
int vex1, vex2;
// 输入图的顶点数和边数
scanf("%d %d", &G.vexnum, &G.arcnum);
// 初始化邻接矩阵
for (int i = 0; i < G.vexnum; ++i)
{
for (int j = 0; j < G.vexnum; ++j)
{
G.arcs[i][j] = 0; // 初始化为0,表示没有边相连
}
}
// 输入边的信息,构建邻接矩阵
for (int k = 0; k < G.arcnum; ++k)
{
scanf("%d %d", &vex1, &vex2);
G.arcs[vex1][vex2] = 1;
G.arcs[vex2][vex1] = 1; // 无向图,边是双向的
}
// 初始化visited数组
for (int i = 0; i < G.vexnum; ++i)
{
visited[i] = 0;
}
int connectedComponents = 0;
for (int i = 0; i < G.vexnum; ++i)
{
if (!visited[i])
{
DFS(&G, i);
++connectedComponents;
}
}
printf("\n");
// 计算边的数目
int edges = 0;
for (int i = 0; i < G.vexnum; ++i)
{
for (int j = i + 1; j < G.vexnum; ++j)
{
if (G.arcs[i][j])
{
++edges;
}
}
}
// 输出连通分量个数和边的数目
printf("%d\n%d\n", connectedComponents, edges);
return 0;
}