Дерева
Дерева є однією з ключових структур даних в алгоритмах і зустрічаються у широкому спектрі задач.
Дерево — це зв'язний, ациклічний, неорієнтований граф.
Граф G = (V, E) називається деревом, якщо він задовольняє такі властивості:
Зв'язність — між будь-якою парою вершин у графі існує шлях.
Ациклічність — граф не містить циклів.
У дереві з вершинами завжди рівно n - 1 ребро.
Основні властивості дерева
1. Зв'язність і унікальність шляхів
У дереві між будь-якою парою вершин існує єдиний шлях.
2. Кількість ребер
Для будь-якого дерева:
3. Відсутність циклів
Додавання навіть одного ребра до дерева завжди створює цикл.
4. Корінь (для кореневого дерева)
Якщо одна вершина обрана як корінь, дерево стає орієнтованим від кореня до його нащадків. Це використовується у рекурсивних обходах та алгоритмах (, та ін.).
5. Піддерева
Будь-яка вершина разом зі своїми нащадками утворює піддерево. Піддерево саме є деревом.
6. Листя
Вершини без нащадків (у кореневому дереві) називаються листям.
7. Глибина та висота
Глибина вершини — це відстань від кореня до цієї вершини.
Висота дерева — це максимальна глибина серед усіх вершин.
8. Центр дерева
Центр — це вершина (або пара суміжних вершин), яка мінімізує максимальну відстань до всіх інших вершин.
Альтернативні визначення дерева
Наступні визначення дерева є еквівалентними і можуть використовуватись у різних контекстах:
Граф без циклів, який стає незв'язним при видаленні будь-якого ребра.
Зв'язний граф з вершинами і n - 1 ребрами.
Ациклічний граф з n - 1 ребрами та однією зв'язною компонентою.
Представлення дерев у коді
Залежно від задачі і типу дерева (загальне, бінарне, кореневе і т.д.), використовуються різні структури даних:
1. Списки суміжності
Цей підхід часто використовується у задачах зі спортивного програмування та при роботі з неорієнтованими чи орієнтованими деревами.
int n;
vector<vector<int>> tree(n); // дерево з n вершинами
// додавання ребра між вершинами u та v
tree[u].push_back(v);
tree[v].push_back(u); // для неорієнтованого дерева2. Масив батьків
Дуже компактне представлення, особливо корисне, коли дерево вже побудовано.
vector<int> parent(n); // parent[i] — батько вершини i
// якщо i — корінь, parent[i] зазвичай встановлюється в -1 або 03. Вказівники / Структури (ООП стиль)
Зазвичай використовується для побудови бінарних дерев, тріє та інших структур, особливо в Python/Java/C++ з використанням об'єктно-орієнтованого програмування.
Бінарне дерево:
struct Node
{
int val;
Node* left;
Node* right;
Node(int v) : val(v), left(nullptr), right(nullptr) {}
};Загальне дерево:
struct Node
{
int val;
vector<Node*> children;
Node(int v) : val(v) {}
};Дано зв'язний неорієнтований граф без петель та кратних ребер. Дозволяється видаляти ребра графа. Потрібно отримати дерево.
Вхідні дані. У першому рядку записано два цілих числа — кількість вершин n~(1 \le n \le 100) та кількість ребер у графі. Далі записано пар цілих чисел, що задають ребра. Гарантується, що граф зв'язний.
Вихідні дані. Виведіть n - 1 пару цілих чисел — ребра, які утворюють дерево. Ребра можна виводити у будь-якому порядку.

4 4
1 2
2 3
3 4
4 11 2
2 3
3 4Дано дерево — простий зв'язний граф без циклів.
Потрібно знайти максимальну кількість ребер, які можна видалити з дерева так, щоб отримати ліс, у якому кожна зв'язна компонента містить парну кількість вершин.
Наприклад, у дереві з вершинами, зображеному нижче, можна видалити не більше ніж ребро, щоб утворити парний ліс.

Вхідні дані. У першому рядку записано два цілих числа: кількість вершин n~(2 \le n \le 100, n — парне) та кількість ребер . У кожному з наступних рядків записано по два цілих числа — вершини, з'єднані ребром. Корінь дерева — вершина .
Вихідні дані. Виведіть максимальну кількість ребер, які можна видалити.

10 9
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 82Дано структуру компанії. Потрібно для кожного працівника порахувати кількість його підлеглих.
Вхідні дані. У першому рядку знаходиться ціле число n~(1 \le n \le 2 \cdot 10^5) — кількість працівників. Працівники пронумеровані числами , , ..., , причому працівник номер є генеральним директором компанії.
Далі йдуть n - 1 цілих чисел: для кожного працівника , , ..., вказано номер його безпосереднього керівника.
Вихідні дані. Виведіть цілих чисел: для кожного працівника , , ..., кількість його підлеглих.

5
1 1 2 34 1 1 0 0Дано дерево, що складається з вершин.
Діаметром дерева називається максимальна відстань між двома вершинами. Знайдіть діаметр заданого дерева.
Вхідні дані. У першому рядку знаходиться ціле число n~(1 \le n \le 2 \cdot 10^5) — кількість вершин у дереві. Вершини пронумеровані від до .
Кожен з наступних n - 1 рядків описує ребро і містить два числа та b~(1 \le a, b \le n), що означає, що між вершинами та є ребро.
Вихідні дані. Виведіть одне ціле число — діаметр дерева.

5
1 2
1 3
3 4
3 53Дано дерево, що складається з вершин.
Для кожної вершини знайдіть максимальну відстань до будь-якої іншої вершини.
Вхідні дані. У першому рядку міститься ціле число n~(1 \le n \le 2 \cdot 10^5) — кількість вершин у дереві. Вершини пронумеровані від до .
Наступні n - 1 рядків описують ребра: кожен рядок містить два числа та b~(1 \le a, b \le n), що означає наявність ребра між вершинами та .
Вихідні дані. Виведіть цілих чисел. Для кожної вершини від до виведіть максимальну відстань до будь-якої іншої вершини дерева.

5
1 2
1 3
3 4
3 52 3 2 3 3Батьки Романа подарували йому неорієнтований, зв’язний, зважений граф з вершинами та n - 1 ребром. Роман хоче знайти загальну довжину всіх шляхів між кожною парою вершин у графі. Довжина шляху визначається як сума ваг ребер, що входять до нього. Оскільки шлях від вершини до вершини такий самий, як і від до , Роман вважає їх одним і тим самим шляхом.
Вхідні дані. У першому рядку задано ціле число n~(2 \le n \le 10^5) — кількість вершин у графі.
Кожен з наступних n - 1 рядків описує ребро і містить три цілі числа: номери двох вершин, з'єднаних ребром (вершини пронумеровані від до ), та вагу ребра.
Вихідні дані. Виведіть загальну довжину всіх різних шляхів між усіма парами вершин, за модулем 10^9.

3
1 2 1
1 3 386
1 2 5
1 3 1
2 4 2
2 5 4
2 6 390Задано кореневе дерево, що складається з вершин. Кожна вершина пофарбована в один із кольорів. Для кожної вершини визначте кількість різних кольорів, що зустрічаються в піддереві з коренем у .
Вхідні дані. У першому рядку записано одне ціле число n~(1 \le n \le 10^6). Наступні рядків описують вершини дерева. -ий рядок містить два цілих числа p_i та c_i, де p_i — батько вершини , а c_i — колір вершини i~(1 \le c_i \le n). Для кореня дерева p_i = 0.
Вихідні дані. Виведіть цілих чисел — по одному для кожної вершини від до . Для кожної вершини виведіть кількість різних кольорів у піддереві з коренем у цій вершині.

5
2 1
3 2
0 3
3 3
2 11 2 3 1 1Після довгого і напруженого робочого тижня жителі Манчестера і Ліверпуля вирішили на вихідних вирушити в похід. Під час прогулянки лісом вони натрапили на унікальне дерево з вершинами. Вершини дерева пронумеровані від до , і кожна з них пофарбована в один з можливих кольорів.
Щоб не нудьгувати, вони вирішили перевірити свою логіку. Коренем дерева є вершина . Для кожної вершини учасники вирішили знайти її найближчого предка такого ж кольору.
Вхідні дані. Перша строка містить два цілі числа і c~(1 \le n, c \le 10^5) — кількість вершин у дереві та кількість можливих кольорів.
Друга строка містить n - 1 ціле число: -те з них вказує батька вершини i + 1.
Третя строка містить цілих чисел — кольори вершин. Кожен колір — це ціле число від до включно.
Вихідні дані. Виведіть цілих чисел в одному рядку: для кожної вершини виведіть номер її найближчого предка з таким самим кольором. Якщо такого предка не існує, виведіть .
5 4
1 1 3 3
1 4 2 1 2-1 -1 -1 1 3У вільний час фермер Джон створив власну платформу для поширення відео під назвою MooTube. На MooTube його корови можуть записувати, публікувати та переглядати багато смішних відео. На цей момент корови завантажили відео, пронумерованих від до .
Проте фермер Джон не до кінця розуміє, як допомогти своїм коровам знаходити нові відео, які їм можуть сподобатися. Він хоче реалізувати систему рекомендацій для кожного відео — список «рекомендованих відео» на основі їхньої схожості з уже переглянутими.
Щоб визначити, наскільки два відео схожі, Джон вводить метрику релевантності. Він вручну оцінює n - 1 пар відео та призначає кожній парі певну оцінку релевантності. Використовуючи ці пари, Джон будує мережу, де кожне відео — це вершина в графі, а обрані пари з'єднані ребрами з відповідними значеннями релевантності.
Для зручності Джон вибирає саме n - 1 пар так, щоб між будь-якими двома відео існував рівно один шлях — іншими словами, мережа відео утворює дерево.
Він вирішує, що релевантність між двома відео має визначатися як мінімальне значення релевантності серед усіх ребер на шляху, що з'єднує ці два відео.
Тепер фермер Джон хоче вибрати значення так, щоб для будь-якого відео на MooTube всі інші відео з релевантністю принаймні до нього відображалися як рекомендації. Однак його турбує, що надто багато рекомендацій можуть відволікати корів від виробництва молока, тому він хоче точно оцінити, скільки відео буде рекомендовано для різних значень .
Фермер Джон звертається до вас по допомогу: вам задано кілька запитів, кожен з яких містить значення та номер відео. Для кожного запиту потрібно визначити, скільки інших відео буде рекомендовано, якщо мінімальна необхідна релевантність дорівнює .
Вхідні дані. Перша стрічка містить два цілі числа та q~(1 \le n, q \le 5000) — кількість відео та кількість запитів відповідно.
Наступні n − 1 стрічок описують пари відео, релевантність яких була вручну оцінена фермером Джоном. Кожна з цих стрічок містить три цілі числа p_i, q_i та r_i~(1 \le p_i, q_i \le n, 1 \le r_i \le 10^9), що означає, що відео p_i та q_i з'єднані ребром із релевантністю r_i.
Далі йдуть стрічок, кожна з яких описує один із запитів фермера Джона. -та стрічка містить два цілі числа k_i та v_i~(1 \le k_i \le 10^9, 1 \le v_i \le n) — це означає, що в -му запиті фермер Джон хоче дізнатись, скільки відео буде рекомендовано для відео v_i, якщо мінімально допустима релевантність для рекомендацій дорівнює k = k_i.
Вихідні дані. Виведіть стрічок. У -тій стрічці виведіть відповідь на -тий запит фермера Джона.

Приклад. Фермер Джон встановив наступні зв'язки між відео:
Відео і відео мають релевантність ,
Відео і відео мають релевантність ,
Відео і відео мають релевантність .
На основі цих даних можемо обчислити релевантність між іншими парами відео:
Відео і відео : релевантність = min(3, 2) = 2,
Відео і відео : релевантність = min(3, 4) = 3,
Відео і відео : релевантність = min(2, 4) = 2.
Розглянемо, які відео будуть рекомендовані для наступних запитів:
Для відео при k = 1, будуть рекомендовані відео , та .
Для відео при k = 3, будуть рекомендовані відео та .
Для відео при k = 4, жодне відео не буде рекомендоване.
4 3
1 2 3
2 3 2
2 4 4
1 2
4 1
3 13
0
2Задано дерево з вершинами. Ребра дерева мають вагу лише або . Потрібно знайти XOR-суму для всіх пар вершин. Обчисліть суму всіх таких XOR-сум.
Вхідні дані. У першому рядку задано число вершин n~(2 \le n \le 10^5) у графі. Наступні n - 1 рядків описують ребра. Кожен рядок містить три цілих числа — номери вершин, які з'єднує ребро (вершини нумеруються від до ), та вагу ребра ( або ).
Вихідні дані. Виведіть суму XOR-сум між усіма парами вершин.

5
1 2 1
2 3 1
2 4 0
4 5 16Задано дерево з вершинами, пронумерованими від до . -те ребро дерева з'єднує вершини a_i та b_i. Вершина пофарбована в колір c_i (у цій задачі кольори задані цілими числами).
Вершина вважається хорошою, якщо найкоротший шлях від вершини до вершини не містить жодної іншої вершини такого самого кольору, як і у вершини , крім самої .
Знайдіть усі хороші вершини.
Вхідні дані. У першому рядку міститься одне ціле число n~(2 \le n \le 10^5) — кількість вершин.
У другому рядку міститься цілих чисел — кольори вершин: c_1, c_2, \dots, c_n~(1 \le c_i \le 10^5).
Кожен з наступних n - 1 рядків містить по два цілих числа a_i та b_i~(1 \le a_i, b_i \le n) — ребра дерева.
Вивід. Виведіть усі хороші вершини по одній у рядку в порядку зростання їхніх номерів.

6
2 7 1 8 2 8
1 2
3 6
3 2
4 3
2 51
2
3
4
610
3 1 4 1 5 9 2 6 5 3
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 101
2
3
5
6
7
8Задано дерево з вершинами та n − 1 ребром. Вершини пронумеровані від до , і -те ребро з'єднує вершини a_i та b_i.
У вас є кольорів. Для кожної вершини дерева потрібно вибрати один із кольорів, дотримуючись наступної умови:
Якщо відстань між двома різними вершинами та менша або дорівнює двом, то та повинні бути пофарбовані в різні кольори.
Скількома способами можна розфарбувати дерево? Знайдіть відповідь за модулем 10^9 + 7.
Вхідні дані. Перший рядок містить два числа та k~(1 \le n, k \le 10^5). Кожен з наступних n - 1 рядків містить два цілих числа a_i та b_i~(1 \le a_i, b_i \le n).
Вихідні дані. Виведіть кількість способів розфарбувати дерево за модулем 10^9 + 7
4 3
1 2
2 3
3 465 4
1 2
1 3
1 4
4 548У країні є міст і n - 1 двосторонніх доріг, так що можливо дістатися з будь-якого міста до будь-якого іншого, використовуючи лише ці дороги. Міста пронумеровані цілими числами від до включно.
Спочатку всі дороги вважаються поганими, але уряд планує покращити стан деяких із них. Громадяни будуть задоволені покращенням, якщо на шляху від столиці, розташованої у місті , до будь-якого іншого міста буде не більше ніж одна погана дорога.
Визначте кількість способів покращити якість деяких доріг, щоб задовольнити цю вимогу. Оскільки відповідь може бути дуже великою, виведіть її по модулю 10^9 + 7.
Вхідні дані. У першому рядку задано одне ціле число n~(2 \le n \le 2 \cdot 10^5) — кількість міст у країні. У другому рядку задано n - 1 додатних цілих чисел p_2, p_3, p_4, \cdots, p_n~(1 \le p_i \le i - 1), що описують дороги в країні. Число p_i означає, що є дорога між містом p_i та містом .
Вихідні дані. Виведіть кількість способів покращити якість доріг по модулю 10^9 + 7.

3
1 146
1 2 2 1 515У ясні літні дні Нюша полюбляє ловити метеликів на свіжому повітрі. Але сьогодні їй трапився особливо хитрий метелик — він залетів до лабіринту й намагається сховатися в ньому.
Лабіринт складається з кімнат, пронумерованих від до , деякі з яких з'єднані між собою коридорами. Відомо, що між будь-якими двома кімнатами існує рівно один простий шлях, який проходить лише через коридори. Іншими словами, лабіринт є деревом з вершинами та n - 1 ребром.
Вхід до лабіринту розташований у кімнаті номер . Листом називається будь-яка кімната, яка з'єднана лише з однією іншою кімнатою і не є коренем (тобто не є кімнатою ). У кожному листі є вихід із лабіринту. Метелик починає свій політ із кімнати в напрямку одного з виходів. Він рухається з сталою швидкістю, ніколи не повертається назад і проходить один коридор за хвилину, переходячи в сусідню кімнату. Усі коридори однакової довжини.
Щоб зловити метелика, Нюша вирішила покликати на допомогу кількох друзів. Спочатку кожен з них може зайняти позицію в будь-якій кімнаті, де є вихід. Щойно метелик почне свій рух із входу в напрямку будь-якого виходу, друзі одразу можуть почати рух з виходів у напрямку до входу. Вони рухаються з тією ж швидкістю, що й метелик. Якщо хтось із них зустріне метелика — чи то в кімнаті, чи посередині коридору — вважається, що його спіймано. Якщо ж метелик досягне виходу, не зустрівши жодного з друзів, він успішно втече на волю.
Допоможи Нюші визначити мінімальну кількість друзів, необхідну для того, щоб гарантовано спіймати метелика незалежно від того, до якого виходу він полетить.
Вхідні дані. Перший рядок містить одне ціле число n~(2 \le n \le 200000) — кількість кімнат у лабіринті.
Наступні n - 1 рядків описують коридори, які з'єднують кімнати. Кожен рядок містить два цілих числа та v~(1 \le u, v \le n, u \ne v) — номери кімнат, з'єднаних коридором.
Гарантується, що задана система коридорів утворює дерево.
Вихідні дані. Виведи одне ціле число — мінімальну кількість друзів, необхідну для гарантованого упіймання метелика.
3
1 2
1 324
1 2
2 3
2 41Кефа вирішив відсвяткувати свою першу велику зарплату походом до ресторану.
Він живе поруч із незвичним парком. Парк представляє собою укорінене дерево з вершинами, вкорінене у вершині . Дім Кефи також знаходиться у вершині . На жаль, у цьому парку мешкають коти, і Кефа вже визначив вершини, в яких ці коти знаходяться.
У листках дерева парку розташовані ресторани. Кефа хоче вибрати ресторан, але він дуже боїться котів. Тому він не піде до ресторану, якщо на шляху від свого дому до ресторану зустріне більше ніж послідовних вершин із котами.
Ваше завдання — допомогти Кефі підрахувати кількість ресторанів, які він може безпечно відвідати.
Вхідні дані. У першому рядку міститься два цілих числа і m~(2 \le n \le 10^5, 1 \le m \le n) — кількість вершин у дереві та максимальна кількість послідовних вершин із котами, яку Кефа може витримати.
У другому рядку міститься цілих чисел a_1, a_2, ..., a_n, де кожне a_i дорівнює (у вершині немає кота) або (у вершині є кіт).
У наступних n - 1 рядках описано ребра дерева у форматі x_i~y_i~(1 \le x_i, y_i \le n, x_i \ne y_i), де x_i і y_i — вершини, з’єднані ребром.
Гарантується, що задана множина ребер утворює дерево.
Вихідні дані. Виведіть кількість листкових вершин, до яких Кефа може дістатися, якщо на шляху з дому до них він зустріне не більше ніж послідовних вершин із котами.

7 1
1 1 0 0 0 0 1
1 2
1 3
2 4
2 5
3 6
3 728 2
1 1 0 1 0 1 0 1
1 2
2 3
2 5
2 6
3 4
6 7
6 82Задано дерево з вершинами. Вершина вважається коренем. Існує рівно один простий шлях між будь-якими двома вершинами.
Позначимо d(i, j) — кількість ребер на шляху від вершини до вершини .
Знайдіть кількість пар вершин таких, що виконується рівність:
Вхідні дані. Перший рядок містить одне ціле число n~(1 \le n \le 10^5) — кількість вершин у дереві.
Кожен з наступних n - 1 рядків містить по два цілих числа, які описують ребра дерева: пари вершин, з'єднаних ребром.
Вихідні дані. Виведіть одне число — кількість пар , для яких виконується d(i, j) = d(i, 1) - d(j, 1).
5
1 2
2 3
2 4
4 513Дано бінарне дерево, яке є ациклічним зв'язним неорієнтованим графом з вершинами та n - 1 ребрами. Кожна вершина має степінь не більше . Коренем є вершина номер , при цьому її степінь не перевищує .
На жаль, корінь дерева інфікований. Наступний процес повторюється разів:
Гусейн або вибирає вершину, яка ще не інфікована (і ще не видалена), та видаляє її разом з усіма інцидентними їй ребрами, або не робить нічого.
Після цього інфекція поширюється на всі вершини, з'єднані ребром з уже інфікованими вершинами (усі раніше інфіковані вершини залишаються інфікованими).
Допоможіть Гусейну визначити максимальну кількість вершин, які він може врятувати від інфекції (зауважимо, що видалені вершини не вважаються врятованими).
Вхідні дані. У першому рядку міститься число n~(2 \le n \le 3 \cdot 10^5) — кількість вершин у дереві.
Кожен з наступних n - 1 рядків містить два цілих числа u_i та v_i~(1 \le u_i, v_i \le n) — ребро дерева.
Гарантується, що граф є бінарним деревом з коренем у вершині .
Вихідні дані. Виведіть одне ціле число — кількість врятованих вершин.
4
1 2
2 3
2 427
1 2
1 5
2 3
2 4
5 6
5 72
Коментарі5