Advertisement
dmkozyrev

1517-RE.cpp

Feb 10th, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.33 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <functional>
  5. #include <cassert>
  6.  
  7. int main() {
  8.     freopen("input.txt", "rt", stdin);
  9.      
  10.     // Чтение количества вершин и степени дерева:
  11.     int nVert, degree;
  12.     scanf("%d %d", &nVert, &degree);
  13.    
  14.     // Список смежностей под ребра дерева:
  15.     std::vector<std::vector<int>> edges(1+nVert, std::vector<int>());
  16.    
  17.     // Чтение ребер:
  18.     for (int b = 2; b <= nVert; ++b) {
  19.         int a;
  20.         scanf("%d", &a);
  21.         edges[a].push_back(b);
  22.     }
  23.    
  24.     // Обход всех вершин с подсчетом величин двух максимальных путей до листьев из каждой вершины:
  25.     std::vector<std::pair<int, int>> height(1+nVert, {-1, -1});
  26.      
  27.     // Рекурсивная функция обхода вершины curr:
  28.     std::function<int(int)> visit = [&](int curr) {
  29.         // Среди всех путей до листьев из текущей вершины вниз нужно найти два максимальных
  30.         std::vector<int> temp{0, 0};
  31.         // Посещаем всех сыновей, сохраняя полученные от них результаты:
  32.         for (auto & next : edges[curr]) {
  33.             temp.push_back(1+visit(next));
  34.         }
  35.         // Сортируем вектор из результатов:
  36.         std::sort(temp.begin(), temp.end(), std::greater<int>());
  37.         // Записываем ответ для текущей вершины, выбирая два максимума:
  38.         height[curr] = {temp[0], temp[1]};
  39.         return temp[0];
  40.     };
  41.    
  42.     // Запуск рекурсивного обхода дерева начиная с корня:
  43.     visit(1);
  44.    
  45.     // Вычисление ответа:
  46.     int64_t max = (height[1].first+1LL) * degree;
  47.     for (int v = 1; v <= nVert; ++v) {
  48.         if (height[v].first && height[v].second) { // Если из текущей вершины два или более путей до листьев
  49.             max = std::max(max, (degree-1LL) * 2 * (height[1].first+1)+ height[v].first + height[v].second + 1);
  50.         }
  51.     }
  52.    
  53.     // Вывод ответа:
  54.     printf("%I64d", max);
  55.    
  56.     return 0;
  57. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement