#include #include #include #include #define rep(i,a,b) for(int i=(a);i<(b);i++) #define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--) #define all(x) begin(x),end(x) #define sz(x) (int)(x).size() using namespace std; using namespace atcoder; using ll=long long; using ld=long double; using vll=vector; using vvll=vector; using vi=vector; using vvi=vector; using pll=pair; using pi=pair; // using mint=modint998244353; // using BoostPoint=boost::polygon::point_data; // using Voronoi=boost::polygon::voronoi_diagram; #include #line 2 "shortest-path/dijkstra-fast.hpp" #line 2 "data-structure/radix-heap.hpp" template struct RadixHeap { using uint = typename make_unsigned::type; static constexpr int bit = sizeof(Key) * 8; array >, bit + 1> vs; array ms; int s; uint last; RadixHeap() : s(0), last(0) { fill(begin(ms), end(ms), uint(-1)); } bool empty() const { return s == 0; } int size() const { return s; } __attribute__((target("lzcnt"))) inline uint64_t getbit(uint a) const { return 64 - _lzcnt_u64(a); } void push(const uint &key, const Val &val) { s++; uint64_t b = getbit(key ^ last); vs[b].emplace_back(key, val); ms[b] = min(key, ms[b]); } pair pop() { if (ms[0] == uint(-1)) { int idx = 1; while (ms[idx] == uint(-1)) idx++; last = ms[idx]; for (auto &p : vs[idx]) { uint64_t b = getbit(p.first ^ last); vs[b].emplace_back(p); ms[b] = min(p.first, ms[b]); } vs[idx].clear(); ms[idx] = uint(-1); } --s; auto res = vs[0].back(); vs[0].pop_back(); if (vs[0].empty()) ms[0] = uint(-1); return res; } }; /** * @brief Radix Heap * @docs docs/data-structure/radix-heap.md */ #line 2 "graph/static-graph.hpp" namespace StaticGraphImpl { template ::value> struct E; template struct E { int to; T cost; E() {} E(const int& v, const T& c) : to(v), cost(c) {} operator int() const { return to; } }; template struct E { int to; E() {} E(const int& v) : to(v) {} operator int() const { return to; } }; template struct StaticGraph { private: template struct Es { It b, e; It begin() const { return b; } It end() const { return e; } int size() const { return int(e - b); } auto&& operator[](int i) const { return b[i]; } }; int N, M, ec; vector head; vector>> buf; vector> es; void build() { partial_sum(begin(head), end(head), begin(head)); es.resize(M); for (auto&& [u, e] : buf) es[--head[u]] = e; } public: StaticGraph(int _n, int _m) : N(_n), M(_m), ec(0), head(N + 1, 0) { buf.reserve(M); } template void add_edge(int u, Args&&... args) { #pragma GCC diagnostic ignored "-Wnarrowing" buf.emplace_back(u, E{std::forward(args)...}); #pragma GCC diagnostic warning "-Wnarrowing" ++head[u]; if ((int)buf.size() == M) build(); } Es>::iterator> operator[](int u) { return {begin(es) + head[u], begin(es) + head[u + 1]}; } const Es>::const_iterator> operator[](int u) const { return {begin(es) + head[u], begin(es) + head[u + 1]}; } int size() const { return N; } }; } // namespace StaticGraphImpl using StaticGraphImpl::StaticGraph; /** * @brief Static Graph * @docs docs/graph/static-graph.md */ #line 5 "shortest-path/dijkstra-fast.hpp" template vector dijkstra(StaticGraph& g, int start = 0) { vector d(g.size(), T(-1)); RadixHeap Q; d[start] = 0; Q.push(0, start); while (!Q.empty()) { auto p = Q.pop(); int u = p.second; if (d[u] < T(p.first)) continue; T du = d[u]; for (auto&& [v, c] : g[u]) { if (d[v] == T(-1) || du + c < d[v]) { d[v] = du + c; Q.push(d[v], v); } } } return d; } template T dijkstra_point(StaticGraph& g, int start, int goal) { vector d(g.size(), T(-1)); RadixHeap Q; d[start] = 0; Q.push(0, start); while (!Q.empty()) { auto p = Q.pop(); int u = p.second; if(u == goal) return d[u]; if (d[u] < T(p.first)) continue; T du = d[u]; for (auto&& [v, c] : g[u]) { if (d[v] == T(-1) || du + c < d[v]) { d[v] = du + c; Q.push(d[v], v); } } } return -1; } template vector> dijkstra_restore(StaticGraph& g, int start = 0) { vector> d(g.size(), {T(-1), -1}); RadixHeap Q; d[start] = {0, -1}; Q.push(0, start); while (!Q.empty()) { auto p = Q.pop(); int u = p.second; if (d[u].first < T(p.first)) continue; T du = d[u].first; for (auto&& [v, c] : g[u]) { if (d[v].first == T(-1) || du + c < d[v].first) { d[v] = {du + c, u}; Q.push(du + c, v); } } } return d; } /* * @brief ダイクストラ法(定数倍高速化) * @docs docs/shortest-path/dijkstra-fast.md **/ int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N,M,L; cin>>N>>M>>L; --L; vi t(N); int cnt=0; rep(i,0,N){ cin>>t[i]; if(t[i]>0)cnt++; } StaticGraphg(N,2*M); rep(i,0,M){ int a,b,c; cin>>a>>b>>c; --a,--b; g.add_edge(a,b,c); g.add_edge(b,a,c); } if(cnt==1){ cout<<0<<'\n'; return 0; } auto dl=dijkstra(g,L); ll ans=LLONG_MAX; rep(r,0,N){ auto dr=dijkstra(g,r); ll sum=0; int best=INT_MAX; rep(i,0,N){ if(t[i]==0)continue; sum+=1LL*t[i]*dr[i]; best=min(best,dl[i]-dr[i]); } ans=min(ans,2*sum+best); } cout<