Submission #1215228

#TimeUsernameProblemLanguageResultExecution timeMemory
1215228madamadam3Network (BOI15_net)C++20
0 / 100
0 ms328 KiB
#include <bits/stdc++.h> using namespace std; void tarjan(int u, int p, vector<vector<int>> &adj, vector<int> &tin, vector<int> &low, vector<bool> &vis, int &timer, bool &is_bridge) { vis[u] = true; tin[u] = low[u] = timer++; for (auto &v : adj[u]) { if (v == p) continue; if (vis[v]) { low[u] = min(low[u], tin[v]); continue; } tarjan(v, u, adj, tin, low, vis, timer, is_bridge); low[u] = min(low[u], low[v]); is_bridge = is_bridge || (low[v] > tin[u]); } } bool has_bridge(vector<vector<bool>> &adjmat) { int n = adjmat.size(); vector<vector<int>> adj(n, vector<int>()); for (int i = 0; i < n; i++) { for (int j = i+1; j < n; j++) { if (adjmat[i][j] != 1) continue; adj[i].push_back(j); adj[j].push_back(i); } } vector<int> tin(n, -1); vector<int> low(n, -1); vector<bool> vis(n, false); int timer = 0; bool is_bridge = false; tarjan(0, 0, adj, tin, low, vis, timer, is_bridge); return is_bridge; } const int MAXLOG = 18; int n, timer = 0; vector<vector<int>> adj, up; vector<pair<int, int>> edges; vector<int> sz, leaves, tin, tout, depth; void get_subtree_size(int u, int p) { sz[u] = 1; for (auto &v : adj[u]) { if (v == p) continue; get_subtree_size(v, u); sz[u] += sz[v]; } if (sz[u] == 1 && p != -1) leaves.push_back(u); } int find_centroid(int u, int p) { for (auto &v : adj[u]) { if (v == p) continue; if (sz[v] * 2 > n) return find_centroid(v, u); } return u; } void dfs(int u, int p) { tin[u] = timer++; if (u == 0) depth[u] = 0; else depth[u] = depth[p] + 1; up[u][0] = p; for (int i = 1; i < MAXLOG; i++) { up[u][i] = up[up[u][i - 1]][i-1]; } for (auto &v : adj[u]) { if (v == p) continue; dfs(v, u); } tout[u] = timer; } bool is_ancestor(int u, int v) { return tin[u] <= tin[v] && tout[u] >= tout[v]; } int find_lca(int u, int v) { if (is_ancestor(u, v)) return u; if (is_ancestor(v, u)) return v; for (int i = MAXLOG - 1; i >= 0; i--) { if (!is_ancestor(up[u][i], v)) { u = up[u][i]; } } return up[u][0]; } int dist(int u, int v) { return depth[u] + depth[v] - 2 * depth[find_lca(u, v)]; } int main() { cin.tie(0)->sync_with_stdio(0); cin >> n; adj.assign(n, vector<int>()); sz.assign(n, -1); tin.assign(n, 0); tout.assign(n, 0); depth.assign(n, 0); up.assign(n, vector<int>(MAXLOG, 0)); for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; u--; v--; adj[u].push_back(v); adj[v].push_back(u); edges.push_back({u, v}); } get_subtree_size(0, -1); int centre = find_centroid(0, -1); leaves.clear(); get_subtree_size(centre, -1); dfs(centre, centre); vector<pair<int, int>> new_edges; set<int> lset(leaves.begin(), leaves.end()); while (!lset.empty()) { int curnode = *lset.begin(); lset.erase(curnode); int endnode = -1, end_dist = -1; for (auto &v : lset) { int vd = dist(curnode, v); if (vd > end_dist) endnode = v, end_dist = vd; } lset.erase(endnode); new_edges.push_back({curnode+1, endnode+1}); if (lset.size() == 1) { int nnc = *lset.begin(); lset.erase(nnc); new_edges.push_back({nnc+1, endnode+1}); } } cout << new_edges.size() << "\n"; for (auto &el : new_edges) { cout << el.first << " " << el.second << "\n"; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...