Advertisement
SorahISA

G. 最短生成樹 (sptree)

Oct 6th, 2022
900
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.20 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using pii = pair<int, int>;
  5. template <typename T>
  6. using prior = std::priority_queue<T, vector<T>, greater<T>>;
  7.  
  8. #define eb emplace_back
  9. #define ef emplace_front
  10. #define ee emplace
  11. #define ALL(x) begin(x), end(x)
  12. #define SZ(x) ((int)(x).size())
  13.  
  14. template <typename T, typename U> bool chmin(T &lhs, U rhs) {return lhs > rhs ? lhs = rhs, 1 : 0;}
  15. template <typename T, typename U> bool chmax(T &lhs, U rhs) {return lhs < rhs ? lhs = rhs, 1 : 0;}
  16.  
  17. const int maxn = 30000 + 5;
  18.  
  19. vector<tuple<int, int, int>> G[maxn];
  20. vector<pii> adj[maxn];
  21. vector<int> sz(maxn, 1), heavy(maxn, -1);
  22. deque<pii> dp;
  23. int P;
  24.  
  25. pii ans{0, 0};
  26.  
  27. void dfs_heavy(int now) {
  28.     int mx_sz = 0;
  29.     for (auto [x, cost] : adj[now]) {
  30.         dfs_heavy(x), sz[now] += sz[x];
  31.         if (chmax(mx_sz, sz[x])) heavy[now] = x;
  32.     }
  33.     sort(ALL(adj[now]), [&](const pii &a, const pii &b) {return sz[a.first] > sz[b.first];});
  34. }
  35.  
  36. void dfs_calc(int now, int dep, int sum) {
  37.     if (SZ(dp) > P-dep-1 and dep <= P-1) {
  38.         if (chmax(ans.first, dp[P-dep-1].first + sum)) ans.second = 0;
  39.         if (ans.first == dp[P-dep-1].first + sum) ans.second += dp[P-dep-1].second;
  40.     }
  41.     for (auto [x, cost] : adj[now]) dfs_calc(x, dep+1, sum+cost);
  42. }
  43.  
  44. void dfs_add(int now, int dep, int sum) {
  45.     if (SZ(dp) <= dep) dp.eb(0, 1);
  46.     if (chmax(dp[dep].first, sum)) dp[dep].second = 0;
  47.     if (dp[dep].first == sum) ++dp[dep].second;
  48.     for (auto [x, cost] : adj[now]) dfs_add(x, dep+1, sum+cost);
  49. }
  50.  
  51. void dfs(int now, bool keep) {
  52.     for (auto [x, cost] : adj[now]) if (x != heavy[now]) dfs(x, 0);
  53.     if (~heavy[now]) {
  54.         dfs(heavy[now], 1);
  55.         for (auto &[val, cnt] : dp) val += adj[now][0].second;
  56.     }
  57.     dp.ef(0, 1);
  58.     if (SZ(dp) > P-1) {
  59.         if (chmax(ans.first, dp[P-1].first)) ans.second = 0;
  60.         if (ans.first == dp[P-1].first) ans.second += dp[P-1].second;
  61.     }
  62.     for (auto [x, cost] : adj[now]) if (x != heavy[now]) dfs_calc(x, 1, cost), dfs_add(x, 1, cost);
  63.     if (!keep) dp.clear();
  64. }
  65.  
  66. vector<int> vis;
  67.  
  68. void dfs_sptree(int now) {
  69.     vis[now] = 1;
  70.     for (auto [x, cost, flag] : G[now]) {
  71.         if (vis[x]) flag = 0;
  72.         else if (flag) adj[now].eb(x, cost), dfs_sptree(x);
  73.     }
  74. }
  75.  
  76. int32_t main() {
  77.     ios_base::sync_with_stdio(0), cin.tie(0);
  78.    
  79.     int N, M; cin >> N >> M >> P;
  80.    
  81.     for (int i = 0, u, v, w; i < M; ++i) {
  82.         cin >> u >> v >> w, --u, --v;
  83.         G[u].eb(v, w, 0), G[v].eb(u, w, 0);
  84.     }
  85.     for (int i = 0; i < N; ++i) sort(ALL(G[i]));
  86.    
  87.     /// sp-dag ///
  88.    
  89.     vector<int> dis(N, INT_MAX >> 1);
  90.     prior<pii> pq;
  91.     pq.ee(dis[0] = 0, 0);
  92.    
  93.     while (SZ(pq)) {
  94.         auto [_d, now] = pq.top(); pq.pop();
  95.         if (dis[now] != _d) continue;
  96.         for (auto [x, cost, flag] : G[now]) if (chmin(dis[x], dis[now] + cost)) pq.ee(dis[x], x);
  97.     }
  98.    
  99.     for (int i = 0; i < N; ++i) {
  100.         for (auto &[x, cost, flag] : G[i]) flag = (dis[x] == dis[i] + cost);
  101.     }
  102.    
  103.     vis.assign(N, 0);
  104.     dfs_sptree(0);
  105.    
  106.     /// dsu on tree ///
  107.    
  108.     dfs_heavy(0);
  109.     dfs(0, 1);
  110.    
  111.     cout << ans.first << " " << ans.second << "\n";
  112.    
  113.     return 0;
  114. }
  115.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement