Advertisement
dmkozyrev

1517-accepted.cpp

Feb 10th, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.22 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.         int max1 = 0, max2 = 0;
  31.         // Посещаем всех сыновей, обновляя максимумы:
  32.         for (auto & next : edges[curr]) {
  33.             int temp = 1 + visit(next);
  34.             if (temp > max1) {
  35.                 max2 = max1;
  36.                 max1 = temp;
  37.             } else if (temp > max2) {
  38.                 max2 = temp;
  39.             }
  40.         }
  41.         // Записываем ответ для текущей вершины:
  42.         height[curr] = {max1, max2};
  43.         return max1;
  44.     };
  45.    
  46.     // Запуск рекурсивного обхода дерева начиная с корня:
  47.     visit(1);
  48.    
  49.     // Вычисление ответа:
  50.     int64_t max = (height[1].first+1LL) * degree;
  51.     for (int v = 1; v <= nVert; ++v) {
  52.         if (height[v].first && height[v].second) { // Если из текущей вершины два или более путей до листьев
  53.             max = std::max(max, (degree-1LL) * 2 * (height[1].first+1)+ height[v].first + height[v].second + 1);
  54.         }
  55.     }
  56.    
  57.     // Вывод ответа:
  58.     printf("%I64d", max);
  59.    
  60.     return 0;
  61. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement