-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy path1724.cpp
More file actions
98 lines (91 loc) · 2.98 KB
/
1724.cpp
File metadata and controls
98 lines (91 loc) · 2.98 KB
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
class SnapShotArray {
public:
vector<vector<int>> snapshots; // index -> {snapshot_i}
vector<vector<int>> values; // index -> value at i snapshot
int currentSnapID;
SnapShotArray(int size) {
snapshots.resize(size, vector<int>({0}));
values.resize(size, vector<int>({0}));
currentSnapID = 0;
}
void snap() {
currentSnapID++;
}
int get(int index, int snapID) {
int p = upper_bound(snapshots[index].begin(), snapshots[index].end(), snapID) - snapshots[index].begin() - 1;
return values[index][p];
}
void set(int index, int value) {
if (currentSnapID == snapshots[index].back()) {
values[index][values[index].size() - 1] = value;
return;
}
snapshots[index].push_back(currentSnapID);
values[index].push_back(value);
}
};
class SnapShotDisjointSet: public SnapShotArray {
public:
SnapShotDisjointSet(int n) : SnapShotArray(n) {
for (int i = 0; i < n; ++i) {
set(i, -1);
}
}
int find(int x, int snapID) {
int pX = get(x, snapID);
if (pX < 0) return x;
return find(pX, snapID);
}
void merge(int x, int y) {
int pX = find(x, currentSnapID);
int pY = find(y, currentSnapID);
if (pX == pY) return;
int sX = -get(pX, currentSnapID);
int sY = -get(pY, currentSnapID);
if (sX >= sY) {
set(pX, -sX - sY);
set(pY, pX);
}
else {
set(pY, -sY - sX);
set(pX, pY);
}
}
bool checkIsConnect(int x, int y, int snapID) {
int pX = find(x, snapID);
int pY = find(y, snapID);
return pX == pY;
}
};
class DistanceLimitedPathsExist {
public:
SnapShotDisjointSet* snapShotDisjointSet;
vector<int> lengthRecords;
static bool compare(const vector<int>& v1, const vector<int>& v2) {
return v1[2] < v2[2];
}
DistanceLimitedPathsExist(int n, vector<vector<int>>& edgeList) {
sort(edgeList.begin(), edgeList.end(), compare);
snapShotDisjointSet = new SnapShotDisjointSet(n);
int currentLength = 0;
for (auto& edge : edgeList) {
if (edge[2] > currentLength) {
lengthRecords.push_back(currentLength);
currentLength = edge[2];
snapShotDisjointSet->snap();
}
snapShotDisjointSet->merge(edge[0], edge[1]);
}
snapShotDisjointSet->snap();
lengthRecords.push_back(currentLength);
}
bool query(int p, int q, int limit) {
int recordID = lower_bound(lengthRecords.begin(), lengthRecords.end(), limit) - lengthRecords.begin() - 1;
return snapShotDisjointSet->checkIsConnect(p, q, recordID);
}
};
/**
* Your DistanceLimitedPathsExist object will be instantiated and called as such:
* DistanceLimitedPathsExist* obj = new DistanceLimitedPathsExist(n, edgeList);
* bool param_1 = obj->query(p,q,limit);
*/