Dijkstra单源最短路径
总提交数: 1725次通过数: 550次通过率: 31.88%
内存限制: 10485760(BYTE)时间限制: 1000(MS)输入限制: 1000(行)输出限制: 1000(行)
题目描述
一个有向图中有 个顶点和 条单向路径 , 请使用Dijkstra算法,求出某一个顶点到其他顶点的最短路径。
Input Format
第一行两个正整数 和 ,分别代表点的数量和路径的数量。 1< <20, 0<= <50
之后 行每行有三个整数 分别表示 路径 的起点、终点序号和路径长度。顶点编号从1开始,0<i,j<=n,0<k<100
源点编号p ,0<p<=n
Output Format
Ⅰ.Dijkstra计算过程;
Ⅱ.输出给定点v到其他各点的路径,以及最短距离。
注意输出格式。
橘色点代表空格。CRLF代表换行。
按照Dijkstra算法获取最短路径顺序进行输出,如果没有路径则输出“No Path to ”【顶点编号,升序排列,中间使用空格隔开】
样例输入输出
样例1
输入:
8 10
1 6 10
1 5 5
6 3 1
6 5 2
3 4 4
4 1 7
4 3 6
5 6 3
5 3 9
5 4 2
1
输出:
No.1 : 1 -> 5 , d = 5
No.2 : 1 -> 5 -> 4 , d = 7
No.3 : 1 -> 5 -> 6 , d = 8
No.4 : 1 -> 5 -> 6 -> 3 , d = 9
No.5 : No Path to 2 7 8
代码:
Dijkstra部分就略过,主要讲一下输出部分的No怎么实现。
很明显,如果要有输出的序号,将输出放入dijkstra内部,随着进程不断输出是一种不错解决方式,然后定义一个time变量每次输出时就加一,这样就能实现序号的输出,值得注意的是time++需要写在if()语句内,有输出时才有time++,最后判断no path to情况,值得注意的是,当没有这种情况存在时,不需要单独输出一个no path to
#include<iostream>
using namespace std;
int *parent;
void output(int start,int m) {
if(parent[m] != start) {
output(start, parent[m]);
}
cout << "-> " << m+1 << " ";
}
int main() {
int n, m;
cin >> n >> m;
int** a = new int* [n];
for (int i = 0; i < n; i++) {
a[i] = new int[n];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = -1;
if (i == j)a[i][j] = 0;
}
}
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
cin >> a[x-1][y-1];
}
int* min = new int[n];
int* visited = new int[n];
min[0] = 0;
for (int i = 0; i < n; i++) {
min[i] = 1000;
visited[i] = 0;
}
parent = new int[n];
int c = 0;
int cur;
cin >> cur;
cur = cur - 1;
int start = cur;
min[cur] = 0;
int time = 1;
int t = 1;
for (int i = 0; i < n; i++) {
parent[i] = start;
}
while (c < n-1) {
for (int j = 0; j < n; j++) {
if (a[cur][j] != -1&& a[cur][j]+min[cur] < min[j]) {
min[j] = a[cur][j] +min[cur];
parent[j] = cur;
}
}
visited[cur] = 1;
int t = 0;
int m;
c = 0;
for (int i = 0; i < n; i++) {
if (visited[i] == 1)c++;
else {
if (t == 0) {
m = i;
t++;
}
else if (min[m] > min[i]) {
m = i;
}
}
}
if (min[m] != 1000) {
cout << "No." << time << " : " << start + 1 << " ";
output(start, m);
cout << ", " << "d = " << min[m] << endl;
time++;
}
cur = m;
}
int* nopath = new int[n];
int end = -1;
for (int i = 0; i < n; i++) {
if (min[i] == 1000) {
end++;
nopath[end] = i;
}
}
if (end >= 0) {
cout << "No."<<time<<" : No Path to";
for (int i = 0; i <= end; i++)
cout << " " << nopath[i]+1;
}
return 0;
}