题目描述
求出下面有向无环图中,顶点“5”到其他所有顶点的最长路径和长度。
输入
根据上面的有向图结构,在内存中用邻接表(Adjacency List)存储该图。
第1行:顶点数
第2行:边数
第3行:一条有向边
第4行:一条有向边
……
输出
第1行:从5到0的最长路径,路径长度
第2行:从5到1的最长路径,路径长度
第3行:从5到2的最长路径,路径长度
第4行:从5到3的最长路径,路径长度
……
样例输入
8
13
5 4 0.35
4 7 0.37
5 7 0.28
5 1 0.32
4 0 0.38
0 2 0.26
3 7 0.39
1 3 0.29
7 2 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93
样例输出
5 1 3 6 4 0
5 1
5 1 3 6 4 7 2
5 1 3
5 1 3 6 4
5 1 3 6
5 1 3 6 4 7
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N = 1e5 + 10; //开一个空间看得舒服些
struct Node{
int v;
double w;
};
vector<Node> g[N];
int n, m; //n为顶点数,m为边数
double dis[N];
bool vis[N];
int pre[N];
void spfa(int st) { //顶点st到其他所有顶点的最长路径和长度
queue<int> q;
q.push(st);
vis[st] = true;
while(q.size()) {
int t = q.front();
q.pop();
vis[t] = false;
for(int i = 0; i < g[t].size(); ++i) {
int j = g[t][i].v;
double w = g[t][i].w;
if(dis[j] < dis[t] + w) {
dis[j] = dis[t] + w;
pre[j] = t;
if(!vis[j]) {
q.push(j);
vis[j] = true;
}
}
}
}
}
void dfs(int u) { //深度遍历
if(u == 5) {
cout << u << ' ';
return ;
}
dfs(pre[u]);
cout << u << ' ';
}
int main() {
cin >> n >> m;
for(int i = 0; i < m; ++i) {
int a, b;
double c;
cin >> a >> b >> c; //输入有向边,以及距离
g[a].push_back({b, c}); //存放结点,包括弧尾和距离
}
spfa(5);
for(int i = 0; i < n; ++i) {
if(i == 5) continue;
dfs(i);
cout << endl;
}
return 0;
}
SPFA算法思路:
建立一个队列,初始时队列里只有起始点,再建立一个表格记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。然后执行松弛操作,用队列里有的点作为起始点去刷新到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后。重复执行直到队列为空。