結果
問題 | No.114 遠い未来 |
ユーザー | t98slider |
提出日時 | 2024-08-03 18:49:46 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,484 ms / 5,000 ms |
コード長 | 2,790 bytes |
コンパイル時間 | 5,656 ms |
コンパイル使用メモリ | 282,364 KB |
実行使用メモリ | 9,088 KB |
最終ジャッジ日時 | 2024-08-03 18:50:03 |
合計ジャッジ時間 | 16,667 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 12 ms
6,816 KB |
testcase_01 | AC | 488 ms
6,812 KB |
testcase_02 | AC | 1,433 ms
9,088 KB |
testcase_03 | AC | 32 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 4 ms
6,940 KB |
testcase_06 | AC | 1,464 ms
9,088 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,944 KB |
testcase_09 | AC | 6 ms
6,944 KB |
testcase_10 | AC | 61 ms
6,940 KB |
testcase_11 | AC | 160 ms
6,940 KB |
testcase_12 | AC | 482 ms
6,944 KB |
testcase_13 | AC | 462 ms
6,940 KB |
testcase_14 | AC | 1,464 ms
9,088 KB |
testcase_15 | AC | 1,484 ms
9,088 KB |
testcase_16 | AC | 223 ms
6,940 KB |
testcase_17 | AC | 322 ms
6,940 KB |
testcase_18 | AC | 1,483 ms
6,944 KB |
testcase_19 | AC | 121 ms
6,944 KB |
testcase_20 | AC | 179 ms
6,944 KB |
testcase_21 | AC | 10 ms
6,944 KB |
testcase_22 | AC | 10 ms
6,944 KB |
testcase_23 | AC | 2 ms
6,940 KB |
testcase_24 | AC | 3 ms
6,940 KB |
testcase_25 | AC | 2 ms
6,944 KB |
testcase_26 | AC | 2 ms
6,944 KB |
testcase_27 | AC | 2 ms
6,940 KB |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> 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; } std::vector<int> idx(N, -1); 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; idx[terminal[i]] = i; } 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; if (idx[u] != -1){ int U = S | (1 << idx[u]); dp[U][u] = std::min(dp[U][u], dp[S][u]); continue; } pq.emplace(dp[S][u], u); } } } } T ans(int v){ assert(0 <= v && v < N); return dp.back()[v]; } }; using namespace std; 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(u, w); } long long S = (1ll << N) - 1; int ans = 1 << 30; for(auto &&v : ter) { cin >> v; v--; S ^= 1ll << v; } sort(edge.begin(), edge.end()); for(long long U = S; U >= 0; U = (U - 1) & S){ int sv = 0; atcoder::dsu uf(N); 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_popcountll(U) == N){ ans = min(ans, sv); } if(U == 0) break; } cout << ans << '\n'; } }