843C - Upgrading Tree
题意:给一棵n个点的树,允许不超过2*n次操作。操作:(x,y,z),删除边(x,y),添加边(y,x),要求满足三个条件(见原题)
题解:
待补~
先贴上dalao代码:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 1234567; 6 7 vector <int> st; 8 int pv[N], sz[N]; 9 vector <int> g[N]; 10 vector <int> jobs[N]; 11 int depth[N]; 12 13 bool flag; 14 15 void dfs(int v, int pr) { 16 st.push_back(v); 17 pv[v] = pr; 18 sz[v] = 1; 19 for (int u : g[v]) { 20 if (u == pr) { 21 continue; 22 } 23 depth[u] = depth[v] + 1; 24 dfs(u, v); 25 sz[v] += sz[u]; 26 } 27 if (flag && depth[v] >= 3) { 28 jobs[st[1]].push_back(v); 29 } 30 st.pop_back(); 31 } 32 33 int main() { 34 int n; 35 scanf("%d", &n); 36 for (int i = 0; i < n - 1; i++) { 37 int x, y; 38 scanf("%d %d", &x, &y); 39 x--; y--; 40 g[x].push_back(y); 41 g[y].push_back(x); 42 } 43 flag = false; 44 dfs(0, -1); 45 vector <int> roots; 46 for (int i = 0; i < n; i++) { 47 int outer = n - sz[i]; 48 if (outer > n / 2) { 49 continue; 50 } 51 bool ok = true; 52 for (int j : g[i]) { 53 if (j == pv[i]) { 54 continue; 55 } 56 if (sz[j] > n / 2) { 57 ok = false; 58 break; 59 } 60 } 61 if (ok) { 62 roots.push_back(i); 63 } 64 } 65 assert(!roots.empty()); 66 flag = true; 67 if ((int) roots.size() == 1) { 68 depth[roots[0]] = 0; 69 dfs(roots[0], -1); 70 } else { 71 depth[roots[0]] = depth[roots[1]] = 0; 72 dfs(roots[0], roots[1]); 73 dfs(roots[1], roots[0]); 74 } 75 vector < pair <int, pair <int, int> > > res; 76 for (int i = 0; i < n; i++) { 77 if (jobs[i].empty()) { 78 continue; 79 } 80 int at = i; 81 for (int &v : jobs[i]) { 82 res.emplace_back(pv[i], make_pair(at, v)); 83 res.emplace_back(v, make_pair(pv[v], i)); 84 at = v; 85 } 86 res.emplace_back(pv[i], make_pair(at, i)); 87 } 88 int cnt = res.size(); 89 printf("%d\n", cnt); 90 for (int i = 0; i < cnt; i++) { 91 printf("%d %d %d\n", res[i].first + 1, res[i].second.first + 1, res[i].second.second + 1); 92 } 93 return 0; 94 }
tourist
时间: 2024-10-20 03:47:31