|
发表于 2023-4-18 18:19:46
|
显示全部楼层
本楼为最佳答案
代码:
- #include <stdio.h>
- #include <stdbool.h>
- #define MAXN 100 // 最大节点数
- #define INF 0x3f3f3f3f // 无穷大
- int n, m; // n为节点数,m为边数
- int G[MAXN][MAXN]; // 邻接矩阵
- int dist[MAXN]; // 距离数组
- int pre[MAXN]; // 前驱节点数组
- bool visited[MAXN]; // 标记数组
- void bfs(int s) {
- for (int i = 0; i < n; i++) {
- dist[i] = INF; // 初始化距离数组
- pre[i] = -1; // 初始化前驱节点数组
- visited[i] = false; // 初始化标记数组
- }
- dist[s] = 0; // 起点距离为0
- visited[s] = true; // 起点已经访问过
- int q[MAXN], front = 0, rear = 0; // 队列及其指针
- q[rear++] = s; // 起点入队
- while (front < rear) { // 队列非空
- int u = q[front++]; // 取出队首节点
- for (int v = 0; v < n; v++) { // 遍历u的邻接点
- if (G[u][v] != INF && !visited[v]) { // 如果v是u的邻接点且未访问过
- dist[v] = dist[u] + 1; // 更新v的距离
- pre[v] = u; // 设置v的前驱节点为u
- visited[v] = true; // 标记v已经访问过
- q[rear++] = v; // v入队
- }
- }
- }
- }
- void print_path(int s, int t) {
- if (s == t) { // 如果起点和终点相同,直接输出起点
- printf("%d", s);
- return;
- }
- int path[MAXN], top = 0; // 路径数组及其指针
- for (int u = t; u != -1; u = pre[u]) { // 从终点往前遍历前驱节点
- path[top++] = u; // 将节点加入路径数组
- }
- for (int i = top - 1; i >= 0; i--) { // 输出路径上的节点
- printf("%d", path[i]);
- if (i > 0) printf("->");
- }
- }
- int main() {
- scanf("%d%d", &n, &m);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- G[i][j] = INF; // 初始化邻接矩阵
- }
- }
- while (m--) {
- int u, v;
- scanf("%d%d", &u, &v);
- G[u][v] = G[v][u] = 1; // 无向图,两个方向都要设置
- }
- int s, t;
- scanf("%d%d", &s, &t);
- bfs(s);
- printf("Shortest path from %d to %d: ", s, t);
- print_path(s, t);
- printf("\n");
- return 0;
- }
复制代码
|
|