結果
問題 | No.114 遠い未来 |
ユーザー | t98slider |
提出日時 | 2024-08-03 19:07:24 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,359 ms / 5,000 ms |
コード長 | 2,206 bytes |
コンパイル時間 | 5,462 ms |
コンパイル使用メモリ | 279,072 KB |
実行使用メモリ | 9,088 KB |
最終ジャッジ日時 | 2024-08-03 19:07:40 |
合計ジャッジ時間 | 15,186 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 12 ms
5,248 KB |
testcase_01 | AC | 444 ms
6,144 KB |
testcase_02 | AC | 1,349 ms
8,960 KB |
testcase_03 | AC | 27 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 3 ms
5,376 KB |
testcase_06 | AC | 1,352 ms
8,960 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 6 ms
5,376 KB |
testcase_10 | AC | 54 ms
5,376 KB |
testcase_11 | AC | 139 ms
5,376 KB |
testcase_12 | AC | 437 ms
6,144 KB |
testcase_13 | AC | 433 ms
6,400 KB |
testcase_14 | AC | 1,359 ms
9,088 KB |
testcase_15 | AC | 1,339 ms
9,088 KB |
testcase_16 | AC | 196 ms
5,376 KB |
testcase_17 | AC | 257 ms
5,376 KB |
testcase_18 | AC | 1,261 ms
5,376 KB |
testcase_19 | AC | 102 ms
5,376 KB |
testcase_20 | AC | 152 ms
5,376 KB |
testcase_21 | AC | 8 ms
5,376 KB |
testcase_22 | AC | 9 ms
5,376 KB |
testcase_23 | AC | 2 ms
5,376 KB |
testcase_24 | AC | 3 ms
5,376 KB |
testcase_25 | AC | 2 ms
5,376 KB |
testcase_26 | AC | 1 ms
5,376 KB |
testcase_27 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using ll = long long; template <class T> std::vector<T> steiner_tree(std::vector<std::vector<std::pair<int, T>>> &G, std::vector<int> &terminal){ const int N = G.size(), t = terminal.size(); if(t == 0) { std::vector<T> ans(N); return ans; } std::vector<std::vector<T>> dp(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); } } } return dp.back(); } 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(); cout << steiner_tree(G, ter)[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'; } }