DuongNhi99

MINPATH

Dec 1st, 2020
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.86 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define root first
  4. #define cost second
  5. using namespace std;
  6.  
  7. const int N = 1005;
  8. const int K = 25;
  9.  
  10. int n, height;
  11. vector<pair<int, int> > graph[N];
  12.  
  13. ll up_cost[N][K], up_root[N][K];
  14. int timer, time_in[N], time_out[N];
  15.  
  16. void init(int u, int p) {
  17.     for (const auto &x : graph[u]) {
  18.         int v = x.root;
  19.         int c = x.cost;
  20.  
  21.         if(v == p) continue;
  22.  
  23.         up_root[v][0] = u;
  24.         up_cost[v][0] = c;
  25.         init(v, u);
  26.     }
  27. }
  28.  
  29. void DFS(int u, int p) {
  30.     time_in[u] = ++timer;
  31.  
  32.     for (int i = 1; i <= height; i++) {
  33.         int mid = up_root[u][i - 1];
  34.         up_root[u][i] = up_root[mid][i - 1];
  35.         up_cost[u][i] = up_cost[u][i - 1] + up_cost[mid][i - 1];
  36.     }
  37.  
  38.     for (const auto &x : graph[u]) {
  39.         int v = x.root;
  40.  
  41.         if (v != p) DFS(v, u);
  42.     }
  43.  
  44.     time_out[u] = ++timer;
  45. }
  46.  
  47. bool is_ancestor(int u, int v) {
  48.     return time_in[u] <= time_in[v] && time_out[v] <= time_out[u];
  49. }
  50.  
  51. ll find_LCA(int u, int v) {
  52.     if (is_ancestor(u, v)) return u;
  53.     if (is_ancestor(v, u)) return v;
  54.  
  55.     for (int i = height; i >= 0; i--) {
  56.         if (up_root[u][i] == 0) continue;
  57.  
  58.         if (!is_ancestor(up_root[u][i], v)) {
  59.             u = up_root[u][i];
  60.         }
  61.     }
  62.  
  63.     return up_root[u][0];
  64. }
  65.  
  66. ll find_sum(int p, int u) {
  67.     ll sum = 0;
  68.  
  69.     for (int i = height; i >= 0; i--) {
  70.         if (up_root[u][i] == 0) continue;
  71.  
  72.         if (is_ancestor(p, up_root[u][i])) {
  73.             sum += up_cost[u][i];
  74.             u = up_root[u][i];
  75.         }
  76.     }
  77.  
  78.     return sum;
  79. }
  80.  
  81. void Print(int s, int t, int mid) {
  82.     vector<int> ans1;
  83.     for(int x = s; x != mid; x = up_root[x][0])
  84.         ans1.push_back(x);
  85.     for(int i = 0; i < ans1.size(); ++i)
  86.         cout << ans1[i] << ' ';
  87.  
  88.     cout << mid << ' ';
  89.  
  90.     vector<int> ans2;
  91.     for(int x = t; x != mid; x = up_root[x][0])
  92.         ans2.push_back(x);
  93.     for(int i = ans2.size() - 1; i >= 0; --i)
  94.         cout << ans2[i] << ' ';
  95. }
  96.  
  97. int main()
  98. {
  99.     //freopen("in.txt", "r", stdin);
  100.     freopen("MINPATH.inp", "r", stdin);
  101.     freopen("MINPATH.out", "w", stdout);
  102.     ios_base::sync_with_stdio(false);
  103.     cin.tie(NULL); cout.tie(NULL);
  104.  
  105.     cin >> n;
  106.     while(true) {
  107.         int u, v, p, q;
  108.         if(!(cin >> u >> v >> p >> q)) break;
  109.  
  110.         int w = p - q;
  111.         graph[u].push_back({v, w});
  112.         graph[v].push_back({u, w});
  113.     }
  114.     height = ceil(log2(n)) + 1;
  115.  
  116.     init(1, 1);
  117.     DFS(1, 1);
  118.  
  119.     ll ans = 1e9;
  120.     ll mid = 0, s = 0, t = 0;
  121.  
  122.     for(int u = 1; u <= n; ++u) {
  123.         for(int v = u + 1; v <= n; ++v) {
  124.             int LCA = find_LCA(u, v);
  125.             int sum = find_sum(u, v);
  126.  
  127.             if(ans >= sum)
  128.                 ans = sum, s = u, t = v, mid = LCA;
  129.         }
  130.     }
  131.  
  132.     cout << ans << '\n';
  133.     Print(s, t, mid);
  134.  
  135.     return 0;
  136. }
Advertisement
Add Comment
Please, Sign In to add comment