結果
問題 | No.114 遠い未来 |
ユーザー | t98slider |
提出日時 | 2024-08-03 18:31:21 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,031 bytes |
コンパイル時間 | 2,934 ms |
コンパイル使用メモリ | 230,408 KB |
実行使用メモリ | 10,016 KB |
最終ジャッジ日時 | 2024-08-03 18:31:38 |
合計ジャッジ時間 | 17,318 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 11 ms
6,812 KB |
testcase_01 | AC | 406 ms
6,812 KB |
testcase_02 | AC | 1,292 ms
9,088 KB |
testcase_03 | WA | - |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 3 ms
6,940 KB |
testcase_06 | AC | 1,314 ms
9,088 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,940 KB |
testcase_09 | AC | 5 ms
6,940 KB |
testcase_10 | AC | 53 ms
6,940 KB |
testcase_11 | AC | 135 ms
6,940 KB |
testcase_12 | AC | 486 ms
6,940 KB |
testcase_13 | AC | 453 ms
6,944 KB |
testcase_14 | AC | 1,412 ms
9,088 KB |
testcase_15 | AC | 1,299 ms
9,216 KB |
testcase_16 | RE | - |
testcase_17 | TLE | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
ソースコード
#include <bits/stdc++.h> template<typename T> struct steiner_tree{ const int N; std::vector<std::vector<std::pair<int, T>>> &G; std::vector<std::vector<T>> dp; steiner_tree(std::vector<std::vector<std::pair<int, T>>> &g) : N(g.size()), G(g) {} void build(std::vector<int> &terminal){ const int t = terminal.size(); if(t == 0) { dp.resize(1, std::vector<T>(N, 0)); return; } dp.resize(1 << t, std::vector<T>(N, std::numeric_limits<T>::max() / 2)); for(int i = 0; i < t; i++){ assert(0 <= terminal[i] && terminal[i] < N); dp[1 << i][terminal[i]] = 0; } std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>, std::greater<std::pair<T, int>>> pq; for(int S = 1; S < (1 << t); S++){ for(int v = 0; v < N; v++){ for(int U = S & (S - 1); U > 0; U = (U - 1) & S){ dp[S][v] = std::min(dp[S][v], dp[U][v] + dp[U ^ S][v]); } } for(int v = 0; v < N; v++) pq.emplace(dp[S][v], v); while(!pq.empty()){ auto [d, v] = pq.top(); pq.pop(); if(d > dp[S][v])continue; for(auto &&[u, w] : G[v]){ if(d + w >= dp[S][u]) continue; dp[S][u] = d + w; pq.emplace(dp[S][u], u); } } } } T ans(int v){ assert(0 <= v && v < N); return dp.back()[v]; } }; using namespace std; struct dsu { public: int csz; dsu() : _n(0) {} dsu(int n) : _n(n), csz(n), parent_or_size(n, -1) {} int merge(int a, int b) { assert(0 <= a && a < _n); assert(0 <= b && b < _n); int x = leader(a), y = leader(b); if (x == y) return x; if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y); csz--; parent_or_size[x] += parent_or_size[y]; parent_or_size[y] = x; return x; } bool same(int a, int b) { assert(0 <= a && a < _n); assert(0 <= b && b < _n); return leader(a) == leader(b); } int leader(int a) { assert(0 <= a && a < _n); if (parent_or_size[a] < 0) return a; return parent_or_size[a] = leader(parent_or_size[a]); } int size(int a) { assert(0 <= a && a < _n); return -parent_or_size[leader(a)]; } std::vector<std::vector<int>> groups() { std::vector<int> leader_buf(_n), group_size(_n); for (int i = 0; i < _n; i++) { leader_buf[i] = leader(i); group_size[leader_buf[i]]++; } std::vector<std::vector<int>> result(_n); for (int i = 0; i < _n; i++) { result[i].reserve(group_size[i]); } for (int i = 0; i < _n; i++) { result[leader_buf[i]].push_back(i); } result.erase( std::remove_if(result.begin(), result.end(), [&](const std::vector<int>& v) { return v.empty(); }), result.end()); return result; } int _n; // root node: -1 * component size // otherwise: parent std::vector<int> parent_or_size; }; int main(){ ios::sync_with_stdio(false); cin.tie(0); int N, M, T; cin >> N >> M >> T; vector<int> ter(T); if(T <= 16){ vector<vector<pair<int,int>>> G(N); for(int i = 0; i < M; i++){ int u, v, w; cin >> u >> v >> w; u--, v--; G[u].emplace_back(v, w); G[v].emplace_back(u, w); } for(auto &&v : ter) cin >> v, v--; int tmp = ter.back(); ter.pop_back(); steiner_tree st(G); st.build(ter); cout << st.ans(tmp) << '\n'; }else{ vector<tuple<int,int,int>> edge(M); for(auto &&[u, v, w] : edge){ cin >> u >> v >> w; u--, v--; swap(v, w); } long long S = (1ll << N) - 1; int ans = 1 << 30, sv; for(auto &&v : ter) { cin >> v; v--; S ^= 1 << v; } sort(edge.begin(), edge.end()); dsu uf(N); for(long long U = S; U >= 0; U = (U - 1) & S){ sv = 0; for(auto &&[w, u, v] : edge){ if((U >> u & 1) || (U >> v & 1) || uf.same(u, v)) continue; uf.merge(u, v); sv += w; } if(uf.size(ter[0]) + __builtin_popcount(U) == N){ ans = min(ans, sv); } fill(uf.parent_or_size.begin(), uf.parent_or_size.end(), -1); } cout << ans << '\n'; } }