DuongNhi99

UPGRANET - VOI 11 (Nâng cấp mạng)

Nov 25th, 2020 (edited)
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.17 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using ll = long long;
  5. using pii = pair<int, int>;
  6. using tii = tuple<int, int, int>;
  7.  
  8. const int N = 1e5 + 5;
  9. const int K = 25;
  10. const int INF = 1e9 + 7;
  11.  
  12. int n, m;
  13. vector<tii> edges;
  14.  
  15. namespace DSU {
  16.  
  17. int parent[N], sizes[N];
  18.  
  19. void reset() {
  20.     iota(parent + 1, parent + n + 1, 1);
  21.     fill(sizes + 1, sizes + n + 1, 1);
  22. }
  23.  
  24. int get_parent(int x) {
  25.     if (parent[x] == x) return x;
  26.     return parent[x] = get_parent(parent[x]);
  27. }
  28.  
  29. bool join(int u, int v) {
  30.     u = get_parent(u);
  31.     v = get_parent(v);
  32.  
  33.     if (u == v) return false;
  34.  
  35.     if (sizes[u] < sizes[v]) swap(u, v);
  36.     parent[v] = u;
  37.     sizes[u] += sizes[v];
  38.     return true;
  39. }
  40. } // namespace DSU
  41.  
  42. namespace LCA {
  43.  
  44. bool visited[N];
  45. int l;
  46. vector<pii> graph[N];
  47. int up_cost[N][K], up_root[N][K];
  48. int timer, time_in[N], time_out[N];
  49.  
  50. void init(int u) {
  51.     visited[u] = true;
  52.  
  53.     for (const auto &[v, c] : graph[u]) {
  54.         if (!visited[v]) {
  55.             up_root[v][0] = u;
  56.             up_cost[v][0] = c;
  57.             init(v);
  58.         }
  59.     }
  60. }
  61.  
  62. void DFS(int u) {
  63.     time_in[u] = ++timer;
  64.     visited[u] = true;
  65.  
  66.     for (int i = 1; i <= l; i++) {
  67.         int mid = up_root[u][i - 1];
  68.         up_root[u][i] = up_root[mid][i - 1];
  69.         up_cost[u][i] = min(up_cost[u][i - 1], up_cost[mid][i - 1]);
  70.     }
  71.  
  72.     for (const auto &[v, _] : graph[u])
  73.         if (!visited[v]) DFS(v);
  74.  
  75.     time_out[u] = ++timer;
  76. }
  77.  
  78. bool is_ancestor(int u, int v) {
  79.     return time_in[u] <= time_in[v] && time_out[v] <= time_out[u];
  80. }
  81.  
  82. int find_LCA(int u, int v) {
  83.     if (is_ancestor(u, v)) return u;
  84.     if (is_ancestor(v, u)) return v;
  85.  
  86.     for (int i = l; i >= 0; i--) {
  87.         if (up_root[u][i] == 0) continue;
  88.  
  89.         if (!is_ancestor(up_root[u][i], v))
  90.             u = up_root[u][i];
  91.     }
  92.     return up_root[u][0];
  93. }
  94.  
  95. int find_min(int p, int u) {
  96.     int minn = 1e9;
  97.  
  98.     for (int i = l; i >= 0; i--) {
  99.         if (up_root[u][i] == 0) continue;
  100.  
  101.         if (is_ancestor(p, up_root[u][i])) {
  102.             minn = min(minn, up_cost[u][i]);
  103.             u = up_root[u][i];
  104.         }
  105.     }
  106.     return minn;
  107. }
  108. } // namespace LCA
  109.  
  110. int main() {
  111. #ifdef LOCAL
  112.     freopen("in1.txt", "r", stdin);
  113. #else
  114.     freopen("UPGRADET.inp", "r", stdin);
  115.     freopen("UPGRADET.out", "w", stdout);
  116. #endif
  117.     ios_base::sync_with_stdio(false);
  118.     cin.tie(nullptr);
  119.  
  120.     cin >> n >> m;
  121.     for (int i = 1; i <= m; ++i) {
  122.         int u, v, c; cin >> u >> v >> c;
  123.         edges.push_back({c, u, v});
  124.     }
  125.     sort(edges.rbegin(), edges.rend());
  126.  
  127.     DSU::reset();
  128.  
  129.     for (const auto &[c, u, v] : edges)
  130.         if (DSU::join(u, v)) {
  131.             LCA::graph[u].push_back({v, c});
  132.             LCA::graph[v].push_back({u, c});
  133.         }
  134.  
  135.     LCA::l = ceil(log2(n)) + 1;
  136.     LCA::init(1);
  137.     fill(LCA::visited + 1, LCA::visited + n + 1, false);
  138.     LCA::DFS(1);
  139.  
  140.     int64_t ans = 0;
  141.     for (const auto &[c, u, v] : edges) {
  142.         int p = LCA::find_LCA(u, v);
  143.         int minn = min(LCA::find_min(p, u), LCA::find_min(p, v));
  144.  
  145.         if (minn > c)
  146.             ans += minn - c;
  147.     }
  148.     cout << ans << '\n';
  149.  
  150.     return 0;
  151. }
  152.  
Advertisement
Add Comment
Please, Sign In to add comment