Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Просто решаю.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
- //
- //KiruxaLight
- #define _CRT_SECURE_NO_WARNINGS
- #define _USE_MATH_DEFINES
- #include <iostream>
- #include <vector>
- #include <string>
- #include <set>
- #include <map>
- #include <algorithm>
- #include <utility>
- #include <cmath>
- #include <iomanip>
- #include <stack>
- #include <deque>
- #include <queue>
- #include <cstdio>
- #include <unordered_map>
- #include <unordered_set>
- #include <numeric>
- #include <cassert>
- using namespace std;
- #define int long long
- #define all(a) a.begin(), a.end()
- #define rall(a) a.rbegin(), a.rend()
- const int INF = 1e9 + 123, MAXN = 2e5 + 47, MEGAINF = 1e18;
- template <class T>
- istream& operator >> (istream& in, vector <T>& a)
- {
- for (auto& i : a)
- in >> i;
- return in;
- }
- template <class T>
- ostream& operator << (ostream& out, vector <T>& a)
- {
- for (auto& i : a)
- out << i << " ";
- return out;
- }
- template <class T, class U>
- istream& operator >> (istream& in, vector <pair <T, U>>& a)
- {
- for (auto& i : a)
- in >> i.first >> i.second;
- return in;
- }
- template <class T, class U>
- ostream& operator << (ostream& out, vector <pair <T, U>>& a)
- {
- for (auto& i : a)
- out << i.first << " " << i.second << endl;
- return out;
- }
- int n;
- vector <vector <int>> g;
- vector <int> pr, tin, tout, h, used;
- int tik = 0;
- void dfs(int v, int p = -1, int high = 0)
- {
- tin[v] = tik++;
- pr[v] = p;
- h[v] = high;
- for (auto& i : g[v])
- if (i != p)
- dfs(i, v, high + 1);
- tout[v] = tik++;
- }
- vector <int> dist, pr2;
- void dfs2(int v, int p = -1, int high = 0)
- {
- dist[v] = high;
- pr2[v] = p;
- for (auto& i : g[v])
- if (i != p)
- dfs2(i, v, high + 1);
- }
- vector <vector <int>> up;
- void init()
- {
- up.resize(20, vector <int>(n));
- for (int i = 0; i < n; ++i)
- up[0][i] = pr[i];
- for (int i = 0; i < 19; ++i)
- for (int j = 0; j < n; ++j)
- {
- int mid = up[i][j];
- if (mid == -1)
- up[i + 1][j] = -1;
- else up[i + 1][j] = up[i][mid];
- }
- }
- bool ancestor(int a, int b)
- {
- return tin[a] <= tin[b] && tout[a] >= tout[b];
- }
- int lca(int a, int b)
- {
- if (ancestor(a, b))
- return a;
- if (ancestor(b, a))
- return b;
- for (int i = 19; i >= 0; --i)
- if (up[i][a] != -1 && !ancestor(up[i][a], b))
- a = up[i][a];
- return pr[a];
- }
- int len(int a, int b)
- {
- return h[a] + h[b] - 2 * h[lca(a, b)];
- }
- vector <int> pos;
- void dfs3(int v, int p = -1)
- {
- for (auto& i : g[v])
- if (i != p)
- dfs3(i, v);
- if (!used[v]) //here you can delete leaves or add them to array and after that you can delete them
- pos.push_back(v);
- }
- signed main()
- {
- setlocale(LC_ALL, "rus");
- /*freopen(".in", "r", stdin);
- freopen(".out", "w", stdout);*/
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- cout.tie(NULL);
- cin >> n;
- g.resize(n);
- tin.resize(n);
- tout.resize(n);
- pr.resize(n);
- h.resize(n);
- dist.resize(n);
- used.resize(n);
- pr2.resize(n);
- for (int i = 0; i < n - 1; ++i)
- {
- int u, v;
- cin >> u >> v;
- --u, --v;
- g[u].push_back(v);
- g[v].push_back(u);
- }
- dfs(0);
- dfs2(0);
- int start = max_element(all(dist)) - dist.begin();
- dist.assign(n, 0);
- pr2.assign(n, -1);
- dfs2(start);
- int fin = max_element(all(dist)) - dist.begin();
- used[start] = 1;
- for (int v = fin; v != start; v = pr2[v])
- used[v] = 1;
- vector <pair <pair <int, int>, int>> ans; //a, b, del
- int res = 0;
- dfs3(start);
- init();
- for (auto& i : pos)
- {
- int length = len(i, start);
- int length2 = len(i, fin);
- if (length > length2)
- {
- ans.push_back({ {i + 1, start + 1}, i + 1 });
- res += length;
- }
- else
- {
- ans.push_back({ {i + 1, fin + 1}, i + 1 });
- res += length2;
- }
- }
- int length = len(fin, start);
- for (int v = fin; v != start; v = pr2[v])
- {
- res += length;
- ans.push_back({ {v + 1, start + 1}, v + 1 });
- --length;
- }
- cout << res << endl;
- for (auto& [u, v] : ans)
- cout << u.first << " " << u.second << " " << v << endl;
- }
- // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
- // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
- // Советы по началу работы
- // 1. В окне обозревателя решений можно добавлять файлы и управлять ими.
- // 2. В окне Team Explorer можно подключиться к системе управления версиями.
- // 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
- // 4. В окне "Список ошибок" можно просматривать ошибки.
- // 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
- // 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement