-
Notifications
You must be signed in to change notification settings - Fork 0
/
Source.cpp
123 lines (107 loc) · 2.53 KB
/
Source.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
114
115
116
117
118
119
120
121
122
123
#include <algorithm>
#include <climits>
#include <iostream>
using namespace std;
const int maxnodes = 200000;
const int maxedges = 1000000;
// graph
int edges;
int last[maxnodes], head[maxedges], previous[maxedges], len[maxedges];
int prio[maxnodes], pred[maxnodes];
void graphClear() {
fill(last, last + maxnodes, -1);
edges = 0;
}
void addEdge(int u, int v, int length) {
head[edges] = v;
len[edges] = length;
previous[edges] = last[u];
last[u] = edges++;
}
// heap
int h[maxnodes];
int pos2Id[maxnodes];
int id2Pos[maxnodes];
int hsize;
void hswap(int i, int j) {
swap(h[i], h[j]);
swap(pos2Id[i], pos2Id[j]);
swap(id2Pos[pos2Id[i]], id2Pos[pos2Id[j]]);
}
void moveUp(int pos) {
while (pos > 0) {
int parent = (pos - 1) >> 1;
if (h[pos] >= h[parent]) {
break;
}
hswap(pos, parent);
pos = parent;
}
}
void add(int id, int prio) {
h[hsize] = prio;
pos2Id[hsize] = id;
id2Pos[id] = hsize;
moveUp(hsize++);
}
void increasePriority(int id, int prio) {
int pos = id2Pos[id];
h[pos] = prio;
moveUp(pos);
}
void moveDown(int pos) {
while (pos < (hsize >> 1)) {
int child = 2 * pos + 1;
if (child + 1 < hsize && h[child + 1] < h[child]) {
++child;
}
if (h[pos] <= h[child]) {
break;
}
hswap(pos, child);
pos = child;
}
}
int removeMin() {
int res = pos2Id[0];
int lastNode = h[--hsize];
if (hsize > 0) {
h[0] = lastNode;
int id = pos2Id[hsize];
id2Pos[id] = 0;
pos2Id[0] = id;
moveDown(0);
}
return res;
}
void dijkstra(int s) {
fill(pred, pred + maxnodes, -1);
fill(prio, prio + maxnodes, INT_MAX);
prio[s] = 0;
hsize = 0;
add(s, 0);
while (hsize) {
int u = removeMin();
for (int e = last[u]; e >= 0; e = previous[e]) {
int v = head[e];
int nprio = prio[u] + len[e];
if (prio[v] > nprio) {
if (prio[v] == INT_MAX)
add(v, nprio);
else
increasePriority(v, nprio);
prio[v] = nprio;
pred[v] = u;
}
}
}
}
int main() {
graphClear();
addEdge(0, 1, 10);
addEdge(1, 2, 5);
addEdge(0, 2, 8);
dijkstra(0);
for (int i = 0; i < 3; i++)
cout << prio[i] << endl;
}