用c++写一个找有向图中最短长度回路的算法,及其思路
时间: 2024-03-17 09:45:48 浏览: 59
这是一个典型的最短路径问题,可以使用 Floyd-Warshall 算法来解决。Floyd-Warshall 算法可以求出任意两个节点之间的最短路径,包括负权边,但要求没有负权回路。如果存在负权回路,则无法求出最短路径。
下面是基于 Floyd-Warshall 算法的 C++ 代码实现:
```cpp
const int INF = 0x3f3f3f3f;
int n; // 顶点个数
int d[MAX_N][MAX_N]; // d[i][j] 表示从 i 到 j 的最短路径长度
// 找有向图中最短长度回路的算法
int shortest_cycle() {
int res = INF;
for (int k = 0; k < n; k++) {
for (int i = 0; i < k; i++) {
for (int j = i + 1; j < k; j++) {
res = min(res, d[i][j] + d[j][k] + d[k][i]);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}
return res;
}
```
具体思路如下:
1. 初始化 d[i][j] 为 i 到 j 的边的长度,如果不存在,则为 INF。
2. 对于每个 k,尝试从 i 到 j 经过 k 的路径是否比直接从 i 到 j 更短,如果是,则更新 d[i][j]=d[i][k]+d[k][j]。
3. 在第二步的过程中,检查是否存在任意两个点 i 和 j 以及另一个点 k,使得路径 i -> j -> k -> i 的长度更短,如果是,则更新 res。
4. 返回 res,即为最短长度回路的长度。
需要注意的是,如果图中存在负权回路,则可能会出现无限循环的情况,因此需要特殊处理。这里的处理方法是,如果在第二步的过程中,某个 d[i][j] 的值变得更小了,则说明存在负权回路。
阅读全文