forked from mpfeifer1/Kattis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharachnophobia.cpp
114 lines (92 loc) · 2.38 KB
/
arachnophobia.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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll inf = (ll)1 << 62;
ll n, m, targettime;
ll snode, enode;
// Returns true if there's a path from start to end with time <= targettime, and with a distance of
// at least dist from a spider
bool path(vector<vector<pair<ll,ll>>>& adj, ll dist, vector<ll>& distspider) {
// if clearly impossible, don't try
if(distspider[snode] < dist) return false;
if(distspider[enode] < dist) return false;
// If the spider is too close, we can't go there
vector<bool> vis(n,false);
for(ll i = 0; i < n; i++) {
if(distspider[i] < dist) vis[i] = true;
}
vector<ll> besttime(n,inf);
besttime[snode] = 0;
// {-weight,dest}
priority_queue<pair<ll,ll>> q;
q.push({0,snode});
while(!q.empty()) {
ll curr = q.top().second;
q.pop();
if(vis[curr]) continue;
vis[curr] = true;
for(auto [next,weight] : adj[curr]) {
if(!vis[next] && besttime[next] > besttime[curr] + weight) {
besttime[next] = besttime[curr] + weight;
q.push({-besttime[next],next});
}
}
}
return besttime[enode] <= targettime;
}
int main() {
// Read in basic info
cin >> n >> m >> targettime;
// Read in graph
// {dest,weight}
vector<vector<pair<ll,ll>>> adj(n);
for(ll i = 0; i < m; i++) {
ll u, v, w;
cin >> u >> v >> w;
adj[u].push_back({v,w});
adj[v].push_back({u,w});
}
// Read in start and end point
cin >> snode >> enode;
// Read in the spiders
ll numspiders;
cin >> numspiders;
vector<ll> spiders(numspiders);
for(auto& i : spiders) cin >> i;
// Run dijkstra's to get closest spider for each node
vector<ll> distspider(n,inf);
vector<bool> visspider(n,false);
// {-weight,dest}
priority_queue<pair<ll,ll>> spider_queue;
for(auto i : spiders) {
distspider[i] = 0;
spider_queue.push({0,i});
}
while(!spider_queue.empty()) {
ll curr = spider_queue.top().second;
spider_queue.pop();
if(visspider[curr]) continue;
visspider[curr] = true;
for(auto [next,weight] : adj[curr]) {
if(distspider[next] > distspider[curr] + weight) {
distspider[next] = distspider[curr] + weight;
spider_queue.push({-distspider[next],next});
}
}
}
// Binary search on the best distance from a spider
ll lo = 0;
ll hi = inf;
ll ans = 0;
while(hi - lo >= 0) {
ll mi = (hi + lo) / 2;
if(path(adj, mi, distspider)) {
lo = mi+1;
ans = max(ans,mi);
}
else {
hi = mi-1;
}
}
cout << ans << endl;
}