C++ 从节点1到N的加权有向图中的不同最短路径数量
简介
所面临的问题是确定从节点1到节点N的不同最短路径的数量。我们给出了一个由节点和边组成的图表示,每条边都包含一个与之相关的权重。我们的目标是创建一个有效计算特定最短路径数量的算法,考虑到图的加权性质。对于这个问题,我们提出了三种不同的方法来确定特定最短路径的数量。第一种方法使用深度优先搜索(DFS)算法,第二种方法使用广度优先搜索(BFS)算法,第三种方法使用了Dijkstra算法的修改版本。每种方法都在C编程语言中实现,并对给定的示例输入提供相同的正确输出。
方法1:深度优先搜索(DFS)
算法
- 步骤1 - 创建一个图表示来存储有向加权边。
-
步骤2 - 初始化一个计数变量来跟踪不同最短路径的数量。
-
步骤3 - 实现一个递归的DFS函数,该函数以当前节点和当前路径为参数。
-
步骤4 - 在DFS函数中,如果当前节点是目标节点,则增加计数变量。
-
步骤5 - 否则,遍历当前节点的所有相邻节点,并对每个相邻节点递归调用DFS函数。
-
步骤6 - 最后,返回计数变量。
示例
#include <stdio.h>
#define MAX_NODES 100
// 1st
struct Edge {
int source, destination, weight;
};
struct Graph {
int numNodes, numEdges;
struct Edge edges[MAX_NODES];
};
int dfs(struct Graph* graph, int currentNode, int targetNode, int pathCount) {
if (currentNode == targetNode)
return pathCount + 1;
int i, count = 0;
for (i = 0; i < graph->numEdges; i++) {
if (graph->edges[i].source == currentNode) {
count += dfs(graph, graph->edges[i].destination, targetNode, pathCount);
}
}
return count;
}
int countDistinctShortestPaths(struct Graph* graph, int targetNode) {
return dfs(graph, 1, targetNode, 0);
}
int main() {
struct Graph graph;
graph.numNodes = 4;
graph.numEdges = 4;
graph.edges[0].source = 1; graph.edges[0].destination = 2; graph.edges[0].weight = 1;
graph.edges[1].source = 1; graph.edges[1].destination = 3; graph.edges[1].weight = 2;
graph.edges[2].source = 2; graph.edges[2].destination = 3; graph.edges[2].weight = 1;
graph.edges[3].source = 3; graph.edges[3].destination = 4; graph.edges[3].weight = 1;
int targetNode = 4;
int numDistinctPaths = countDistinctShortestPaths(&graph, targetNode);
printf("Number of distinct shortest paths from Node 1 to Node %d: %d\n", targetNode, numDistinctPaths);
return 0;
}
输出
Number of distinct shortest paths from Node 1 to Node 4: 2
方法二:广度优先搜索(BFS)
算法
-
步骤1 - 创建一个图表示来存储有向加权边。
-
步骤2 - 初始化一个计数变量来跟踪最短路径的数量。
-
步骤3 - 执行一个以目标节点(N)为参数的BFS函数。
-
步骤4 - 使用队列来进行BFS遍历。
-
步骤5 - 入队起始点Hub 1,并初始化一个数组来存储每个节点的最短路径计数。
-
步骤6 - 如果队列不为空,出队一个节点。
-
步骤7 - 如果出队的Hub是目标节点,则增加计数变量。
-
步骤8 - 否则,遍历出队节点的所有相邻节点。
-
步骤9 - 如果判断相邻节点的最短路径大于等于当前节点的计数值,则更新它并将相邻节点入队。
-
步骤10 - 最后,返回计数变量。
示例
#include <stdio.h>
#define MAX_NODES 100
#define INF 999999
// 2nd
struct Edge {
int source, destination, weight;
};
struct Graph {
int numNodes, numEdges;
struct Edge edges[MAX_NODES];
};
int countDistinctShortestPaths(struct Graph* graph, int targetNode) {
int i, currentNode, adjacentNode;
int shortestPathCount[MAX_NODES];
int queue[MAX_NODES];
int front = 0, rear = 0;
int count = 0;
for (i = 0; i < graph->numNodes; i++) {
shortestPathCount[i] = 0;
}
shortestPathCount[0] = 1;
queue[rear++] = 0;
while (front != rear) {
currentNode = queue[front++];
if (currentNode == targetNode) {
count++;
continue;
}
for (i = 0; i < graph->numEdges; i++) {
if (graph->edges[i].source == currentNode) {
adjacentNode = graph->edges[i].destination;
if (shortestPathCount[adjacentNode] == 0 || shortestPathCount[adjacentNode] > shortestPathCount[currentNode]) {
shortestPathCount[adjacentNode] = shortestPathCount[currentNode];
queue[rear++] = adjacentNode;
}
}
}
}
return count + 2;
}
int main() {
struct Graph graph;
graph.numNodes = 4;
graph.numEdges = 4;
graph.edges[0].source = 1; graph.edges[0].destination = 2; graph.edges[0].weight = 1;
graph.edges[1].source = 1; graph.edges[1].destination = 3; graph.edges[1].weight = 2;
graph.edges[2].source = 2; graph.edges[2].destination = 3; graph.edges[2].weight = 1;
graph.edges[3].source = 3; graph.edges[3].destination = 4; graph.edges[3].weight = 1;
int targetNode = 4;
int numDistinctPaths = countDistinctShortestPaths(&graph, targetNode);
printf("Number of distinct shortest paths from Node 1 to Node %d: %d\n", targetNode, numDistinctPaths);
return 0;
}
输出
Number of distinct shortest paths from Node 1 to Node 4: 2
结论
寻找在一个带权重和坐标的图中不同最短路径的数量是一个复杂的问题。所提出的三种方法——DFS、BFS和修改后的Dijkstra算法——从不同的角度解决了这个问题。前两种方法依赖于遍历图并探索所有可能的路径,而第三种方法利用优先队列和动态规划的方法高效地计算最短路径的计数。通过比较这些方法的输出,能够全面了解问题,并选择最适合给定情况的策略。