結果
問題 | No.114 遠い未来 |
ユーザー | wanui |
提出日時 | 2024-07-30 01:09:31 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 3,840 ms / 5,000 ms |
コード長 | 6,350 bytes |
コンパイル時間 | 3,047 ms |
コンパイル使用メモリ | 234,140 KB |
実行使用メモリ | 8,064 KB |
最終ジャッジ日時 | 2024-07-30 01:09:53 |
合計ジャッジ時間 | 20,556 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 45 ms
6,816 KB |
testcase_01 | AC | 1,712 ms
6,944 KB |
testcase_02 | AC | 298 ms
6,944 KB |
testcase_03 | AC | 52 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,944 KB |
testcase_05 | AC | 15 ms
6,940 KB |
testcase_06 | AC | 704 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,940 KB |
testcase_08 | AC | 1 ms
6,940 KB |
testcase_09 | AC | 37 ms
6,940 KB |
testcase_10 | AC | 293 ms
6,944 KB |
testcase_11 | AC | 2,721 ms
8,064 KB |
testcase_12 | AC | 1,297 ms
6,940 KB |
testcase_13 | AC | 3,840 ms
6,940 KB |
testcase_14 | AC | 662 ms
6,944 KB |
testcase_15 | AC | 1,892 ms
6,940 KB |
testcase_16 | AC | 326 ms
6,940 KB |
testcase_17 | AC | 319 ms
6,944 KB |
testcase_18 | AC | 1,496 ms
6,940 KB |
testcase_19 | AC | 154 ms
6,944 KB |
testcase_20 | AC | 186 ms
6,940 KB |
testcase_21 | AC | 12 ms
6,940 KB |
testcase_22 | AC | 12 ms
6,940 KB |
testcase_23 | AC | 2 ms
6,944 KB |
testcase_24 | AC | 3 ms
6,940 KB |
testcase_25 | AC | 2 ms
6,940 KB |
testcase_26 | AC | 2 ms
6,940 KB |
testcase_27 | AC | 2 ms
6,944 KB |
ソースコード
#include <bits/stdc++.h> // clang-format off using namespace std; using ll=long long; using ull=unsigned long long; const ll INF=4e18; void print0(){}; template<typename H,typename... T> void print0(H h,T... t){cout<<h;print0(t...);} void print1(){print0("\n");}; template<typename H,typename... T>void print1(H h,T... t){print0(h);if(sizeof...(T)>0)print0(" ");print1(t...);} #define debug1(a) { cerr<<#a<<":"<<a<<endl; } #define debug2(a,b) { cerr<<#a<<":"<<a<<" "<<#b<<":"<<b<<endl; } #define debug3(a,b,c) { cerr<<#a<<":"<<a<<" "<<#b<<":"<<b<<" "<<#c<<":"<<c<<endl; } #define debug4(a,b,c,d) { cerr<<#a<<":"<<a<<" "<<#b<<":"<<b<<" "<<#c<<":"<<c<<" "<<#d<<":"<<d<<endl; } // clang-format on namespace SteinerTree { ll solve(vector<vector<pair<int, ll>>>& graph, vector<bool>& is_city) { int N = graph.size(); int K = 0; vector<int> cityid(N, -1); for (int u = 0; u < N; u++) { if (is_city[u]) { cityid[u] = K; K++; } } ll ans = INF; { vector<vector<ll>> dp(N, vector<ll>(1 << K, INF)); for (int u = 0; u < N; u++) { if (cityid[u] >= 0) { int city = cityid[u]; dp[u][1 << city] = 0; } dp[u][0] = 0; } for (int s = 1; s < (1 << K); s++) { for (int u = 0; u < N; u++) { for (int j = s;; j = (j - 1) & s) { int k = s ^ j; // 残り if (k > 0 && j > 0) { dp[u][s] = min(dp[u][s], dp[u][j] + dp[u][k]); } if (!j) break; } } priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq; for (int u = 0; u < N; u++) { int city = cityid[u]; if (dp[u][s] == INF) continue; pq.push({dp[u][s], u}); } vector<bool> done(N); while (pq.size()) { ll cost; int u; tie(cost, u) = pq.top(); pq.pop(); if (done[u]) continue; done[u] = true; dp[u][s] = min(dp[u][s], cost); if (cityid[u] >= 0) { int t = (1 << cityid[u]) | s; dp[u][t] = min(dp[u][t], cost); } for (auto e : graph[u]) { pq.push({e.second + cost, e.first}); } } } for (int u = 0; u < N; u++) { ans = min(ans, dp[u][(1 << K) - 1]); } } return ans; } }; // namespace SteinerTree namespace LargeSolver { class unionfind { public: vector<int> partition; vector<int> rank; vector<int> siz; int n; unionfind(int n_) { partition.resize(n_); rank.resize(n_); siz.resize(n_); for (int x = 0; x < n_; x++) { partition[x] = x; rank[x] = 0; siz[x] = 1; } n = n_; } int find(int x) { if (partition[x] == x) { return x; } else { partition[x] = find(partition[x]); return partition[x]; } } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) { return; } int sx = siz[x]; int sy = siz[y]; if (rank[x] < rank[y]) { partition[x] = y; } else { partition[y] = x; if (rank[x] == rank[y]) { rank[x]++; } } siz[find(x)] = sx + sy; } bool same(int x, int y) { return find(x) == find(y); } int clstsize(int x) { return siz[find(x)]; } vector<pair<int, vector<int>>> get_clusters() { vector<vector<int>> con(n); for (int i = 0; i < n; i++) { con[find(i)].push_back(i); } vector<pair<int, vector<int>>> result; for (int i = 0; i < n; i++) { if (con[i].size() > 0) { vector<int> members = con[i]; result.push_back({i, members}); } } return result; } }; int solve(vector<vector<pair<int, ll>>>& graph, vector<bool>& is_city) { int N = graph.size(); vector<int> viintages; for (int u = 0; u < N; u++) { if (!is_city[u]) viintages.push_back(u); } vector<int> edgs; for (int u = 0; u < N; u++) { for (auto e : graph[u]) { int v = e.first; int c = e.second; if (u > v) continue; edgs.push_back(c * (1 << 20) + u * (1 << 10) + v); } } sort(edgs.begin(), edgs.end()); int ans = 1e9; int m = viintages.size(); for (int i = 0; i < (1 << m); i++) { int first_city = N; int usenum = 0; vector<bool> use(N); for (int u = 0; u < N; u++) { if (is_city[u]) { first_city = min(first_city, u); use[u] = true; usenum++; } } for (int j = 0; j < m; j++) { if ((i >> j) & 1) { use[viintages[j]] = true; usenum++; } } int now = 0; auto uf = unionfind(N); for (auto e : edgs) { int c = e >> 20; int u = (e >> 10) & 1023; int v = (e & 1023); if (!use[u] || !use[v]) continue; if (!uf.same(u, v)) { uf.unite(u, v); now += c; } } if (uf.clstsize(first_city) == usenum) { ans = min(ans, now); } } return ans; } }; // namespace LargeSolver int main() { ll N, M, T; cin >> N >> M >> T; vector<vector<pair<int, ll>>> graph(N); for (ll i = 0; i < M; i++) { ll u, v, c; cin >> u >> v >> c; u--; v--; graph[u].push_back({v, c}); graph[v].push_back({u, c}); } vector<bool> is_city(N); for (ll i = 0; i < T; i++) { ll u; cin >> u; u--; is_city[u] = true; } if (T <= 14) { print1(SteinerTree::solve(graph, is_city)); } else { print1(LargeSolver::solve(graph, is_city)); } }