您的位置:首页 > 大数据 > 人工智能

第十五章 GRL_1_C:All Pairs Shortest Path 所有点对间最短路径

2017-12-31 01:34 323 查看

知识点

负环:所有边的权值之和为负

弗洛伊德(Warshall-Floyd)算法

条件

不包含负环的图

执行步骤

设Di,j,k为从i到j的只以(1..k)集合中的节点为中间節点的最短路径的长度。

若最短路径经过点k,则Di,j,k=Di,k,k−1<
4000
/span>+Dk,j,k−1;

若最短路径不经过点k,则Di,j,k=Di,j,k−1。

因此,Di,j,k=min(Di,j,k−1,Di,k,k−1+Dk,j,k−1)。

性质

判断图G是否存在负环,如果G的某顶点v到顶点v(自身)的最短路径为负,就证明G中存在负环。

问题链接

GRL_1_C:All Pairs Shortest Path

问题内容

求出所有点对间最短路径,如果不能达到则输出INF。

思路

利用floyd算法

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxx = 110;
const LL INF = (1LL << 32);

int n,q;
LL d[maxx][maxx];

void floyd() {
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
if (d[i][k] == INF)
continue;
for (int j = 0; j < n; j++) {
if (d[k][j] == INF)
continue;
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}
}
int main()
{
int u, v, c;
scanf("%d %d", &n, &q);

for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
d[i][j] = i == j ? 0 : INF;
}

// 输入权值
for (int i = 0; i < q; i++) {
scanf("%d %d %d", &u, &v, &c);
d[u][v] = c;
}

floyd();

// 判断是否存在负环
bool negative = false;
for (int i = 0; i < n; i++)
if (d[i][i] < 0)
negative = true;

if (negative)
printf("NEGATIVE CYCLE\n");
else {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (d[i][j] == INF)
printf("INF");
else
printf("%d", d[i][j]);
printf("%c", j == n - 1 ? '\n' : ' ');
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  floyd