采用邻接表存储结构,编写一个判别无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的C语言算法。
时间: 2024-02-25 16:55:41 浏览: 74
无向图的邻接表存储及输出
4星 · 用户满意度95%
以下是判断无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的C语言算法:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXV 1000 // 最大顶点数
typedef struct node {
int v; // 邻接点编号
struct node *next; // 指向下一个邻接点的指针
} Node;
typedef struct {
Node *first; // 指向第一个邻接点的指针
} AdjList[MAXV]; // 邻接表类型
typedef struct {
int n; // 顶点数
AdjList adjList; // 邻接表
} Graph;
bool dfs(Graph *g, int v, int t, int k, bool visited[]) {
if (k == 0) { // 搜索到了指定长度的路径
if (v == t) { // 路径的终点是t
return true;
} else {
return false;
}
} else {
visited[v] = true; // 标记当前顶点为已访问
Node *p = g->adjList[v].first;
while (p != NULL) {
if (!visited[p->v]) { // 如果邻接点还没有被访问过
if (dfs(g, p->v, t, k - 1, visited)) { // 递归搜索
return true;
}
}
p = p->next;
}
visited[v] = false; // 回溯,取消标记
return false;
}
}
bool hasPath(Graph *g, int s, int t, int k) {
bool visited[MAXV] = {false}; // 标记是否已经访问过的数组
return dfs(g, s, t, k, visited);
}
int main() {
int n, m;
scanf("%d %d", &n, &m); // 输入顶点数和边数
Graph g;
g.n = n;
for (int i = 0; i < n; i++) {
g.adjList[i].first = NULL;
}
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v); // 输入一条边的两个端点
Node *p = (Node *) malloc(sizeof(Node));
p->v = v;
p->next = g.adjList[u].first;
g.adjList[u].first = p;
p = (Node *) malloc(sizeof(Node));
p->v = u;
p->next = g.adjList[v].first;
g.adjList[v].first = p;
}
int s, t, k;
scanf("%d %d %d", &s, &t, &k); // 输入起点、终点和路径长度
if (hasPath(&g, s, t, k)) {
printf("存在长度为%d的简单路径\n", k);
} else {
printf("不存在长度为%d的简单路径\n", k);
}
return 0;
}
```
算法思路:
首先输入无向图的邻接表存储结构,然后输入需要判断的起点、终点和路径长度。接着调用 `hasPath()` 函数递归搜索两点之间是否存在一条长度为 k 的简单路径,该函数里面调用了 `dfs()` 函数进行深度优先搜索。其中, `visited[]` 数组用于标记顶点是否已经访问过,如果搜索到了指定长度的路径,就判断路径的终点是否为 t。
时间复杂度为 O(n^k),其中 n 为顶点数,k 为路径长度。
阅读全文