forked from Silver-Taurus/algorithms_and_data_structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dijkstra-shortest-reach.cpp
114 lines (105 loc) · 3.34 KB
/
dijkstra-shortest-reach.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* Given a graph consisting N nodes (labelled 1 to N) where a specific given node S represents the starting position S
* and an edge between two nodes is of a given length, which may or may not be equal to other lengths in the graph.
* It is required to calculate the shortest distance from the start position (Node S) to all of the other nodes in the graph.
* Note 1: If a node is unreachable , the distance is assumed as −1.
*
* Input Format
* The first line contains T, denoting the number of test cases.
* First line of each test case has two integers N, denoting the number of nodes in the graph and M,
* denoting the number of edges in the graph.
* The next M lines each consist of three space separated integers x y w, where x and y
* denote the two nodes between which the undirected edge exists, w denotes the length of edge between these corrresponding nodes.
* The last line has an integer S, denoting the starting position.
*
* Output Format
* For each of the T test cases, Print a single line consisting N−1 space separated integers denoting
* the shortest distance of N−1 nodes from starting position S. For unreachable nodes, print −1.
*
* If there are edges between the same pair of nodes with different weights,
* they are to be considered as is, like multiple edges.
*/
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <list>
#include <climits>
#include <set>
using namespace std;
vector<int> dist;
struct lstDist {
bool operator()(int u, int v) const {
return make_pair(dist[u], u) < make_pair(dist[v], v);
}
};
class Graph {
int N;
vector<vector<int>> weights;
int S;
public:
Graph( int n )
: N{n}, weights(N, vector<int>(N, -1)){}
void addEdge( int x, int y, int w) {
if (weights[x-1][y-1] == -1 || (weights[x-1][y-1] != -1 && weights[x-1][y-1] > w )) {
weights[x-1][y-1] = w;
weights[y-1][x-1] = w;
}
}
void setStart(int s) {
S = s-1;
dist[S] = 0;
}
void distance() {
set<int, lstDist> q;
q.insert(S);
while(!q.empty()) {
int u = *q.begin();
q.erase(q.begin());
for( int v = 0; v < N ; ++v ) {
if (weights[u][v] != -1) {
int newDist = dist[u] + weights[u][v];
if (newDist < dist[v]) {
dist[v] = newDist;
if (q.count(v)) {
q.erase(v);
}
q.insert(v);
}
}
}
}
}
void printDistance() {
for ( unsigned int i = 0; i < dist.size(); ++i ) {
if ( int(i) != S) {
if (dist[i] == INT_MAX) dist[i] = -1;
std::cout << dist[i] << " ";
}
}
std::cout << std::endl;
}
};
int main() {
int T, N, M, x, y, w, S;
cin >> T;
while( T ) {
cin >> N >> M;
dist.resize(N);
for( int i = 0; i < N; ++i) {
dist[i] = INT_MAX;
}
Graph G(N);
for ( int i = 0; i < M; ++i) {
cin >> x >> y >> w;
G.addEdge(x, y, w);
}
cin >> S;
G.setStart(S);
G.distance();
G.printDistance();
--T;
}
return 0;
}