Advertisement
dmkozyrev

compare.cpp

May 14th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.07 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3.  
  4. long long solveYuri(int64_t n, int x, int y, std::vector<std::pair<int, int>> arr) {
  5.     std::vector<std::vector<std::pair<int, bool>>> graph(300000);
  6.     int64_t sum, a, b, c, d;
  7.  
  8.     // Удаляет путь от a в b
  9.     std::function<bool(int, int64_t)> find = [&](int from , int64_t to) {
  10.         int i=0;
  11.         if(to == b) {
  12.             for(; graph[to][i].first != from; i++);
  13.             graph[to][i].second = false;
  14.             return false;
  15.         }
  16.         bool fnd = true;
  17.         for(; i<graph[to].size() && fnd; i++) {
  18.             if (graph[to][i].first != from) {
  19.                 fnd = find(to, graph[to][i].first);
  20.                 if (!fnd) {
  21.                     graph[to][i].second = false;
  22.                     if (from != -1) {
  23.                         int j=0;
  24.                         for(; graph[to][j].first != from; j++);
  25.                         graph[to][j].second = false;
  26.                     }
  27.     //                std::cout << to << ' ' << graph[to][i].first << '\n';
  28.                 }
  29.             }
  30.         }
  31.         return fnd;
  32.     };
  33.  
  34.     // Сколько вершин в компоненте связности
  35.     std::function<int64_t(int, int64_t)> many = [&](int from , int64_t to) {
  36.         int i=0;
  37.         if (from != -1) {
  38.             for(; graph[to][i].first != from; i++);
  39.             graph[to][i].second = false;
  40.         }
  41.         int64_t s = 1;
  42.         for(i=0; i<graph[to].size() && graph[to][i].first != from; i++) {
  43.             if (graph[to][i].second) {
  44.                 s += many(to, graph[to][i].first);
  45.                 graph[to][i].second = false;
  46.     //            std::cout << to << ' ' << graph[to][i].first << '\n';
  47.             }
  48.         }
  49.         return s;
  50.     };
  51.  
  52.     a = x-1;
  53.     b = y-1;
  54.     sum = n * (n-1);
  55.     for (auto& p : arr) {
  56.         c = p.first;
  57.         d = p.second;
  58.         c--;
  59.         d--;
  60.         graph[c].push_back({d, true});
  61.         graph[d].push_back({c, true});
  62.     }
  63.  
  64.     find(-1, a);
  65.  
  66.     int64_t s1 = many(-1, a);
  67.  
  68.     int64_t s2 = many(-1, b);
  69.  
  70.     return sum - s1 * s2;
  71. }
  72.  
  73. long long solveDmitry(int n, int x, int y, const std::vector<std::pair<int, int>>& arr) {
  74.     --x, --y;
  75.    
  76.     std::vector<std::vector<int>> edges(n);
  77.    
  78.     for (int i = 0; i < n-1; ++i) {
  79.         int a = arr[i].first-1, b = arr[i].second-1;
  80.         edges[a].push_back(b);
  81.         edges[b].push_back(a);
  82.     }
  83.    
  84.     std::vector<int> size(n);  // size[v] = size subtree of vertex v
  85.     std::vector<bool> is_x(n); // is_x[v] = true if vertex x in subtree of vertex v
  86.    
  87.     std::function<void(int, int)> visit = [&](const int curr, const int parent) {
  88.         size[curr]++;
  89.         if (curr == x) {
  90.             is_x[curr] = true;
  91.         }
  92.         for (auto next : edges[curr]) {
  93.             if (next != parent) {
  94.                 visit(next, curr);
  95.                 size[curr] += size[next];
  96.                 if (is_x[next] && !is_x[curr]) { // vertex x in subtree[curr] because vertex x in subtree[next]
  97.                     is_x[curr] = is_x[next];
  98.                 }
  99.             }
  100.         }
  101.     };
  102.    
  103.     visit(y, y);
  104.    
  105.     long long sum_without_x = 1;
  106.     long long count_with_x = 0; // for check myself
  107.     for (auto next : edges[y]) {
  108.         if (!is_x[next]) {
  109.             sum_without_x += size[next];
  110.         } else {
  111.             count_with_x++;
  112.         }
  113.     }
  114.     assert(count_with_x == 1); // check myself
  115.     // can't wolk from subtree x in subtree[y] \ subtree[v], which is_x[v] = false
  116.     return 1LL * n * (n-1) - 1LL * size[x] * sum_without_x;
  117. }
  118. /*
  119. void gen(int n, int& x, int& y,std::vector<std::pair<int, int>>& arr) {
  120.     arr.assign(
  121. }
  122. */
  123. int main() {
  124.    
  125.     int n, x, y;
  126.     std::vector<std::pair<int, int>> arr;
  127.     std::cin >> n >> x >> y;
  128.     for (int i = 0; i < n-1; ++i) {
  129.         int a, b; std::cin >> a >> b;
  130.         arr.push_back({a, b});
  131.     }
  132.    
  133.     std::cout << "Dmitry answer = " << solveDmitry(n, x, y, arr) << ", but Yuri answer = " << solveFalse(n, x, y, arr) << std::endl;
  134.    
  135.     return 0;
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement