제출 #384153

#제출 시각아이디문제언어결과실행 시간메모리
384153dapigNetwork (BOI15_net)C++11
100 / 100
919 ms63364 KiB
#include <cstdio> #include <iostream> #include <vector> #include <queue> #include <algorithm> #include <set> #include <map> #include <utility> using namespace std; int n; vector<int> graph[500005]; int start; int leaves[500005]; int et[500005]; int marker = 0; int etrev[500005]; int bit[500005]; void upd(int n, int inc) { n++; while (n < 500005) { bit[n] += inc; n += (n&-n); } } int find(int n) { int s = 0; n++; while (n > 0) { s += bit[n]; n -= (n&-n); } return s; } int findfirst(int n) { if (graph[n].size()==1) return etrev[n]; int l = 0, r = 500005, v = find(etrev[n]); int best = 500004; while (l < r) { int m = (l+r)/2; if (find(m) > v) { best = m; r = m; } else l = m+1; } return best; } int leaffind(int n, int p) { et[marker] = n; marker++; etrev[et[marker-1]] = marker-1; int vis = 0; for (int i : graph[n]) { if (i == p) continue; vis += leaffind(i, n); } if (vis == 0) { leaves[n] = 1; upd(marker-1, 1); return 1; } leaves[n] = vis; return vis; } vector<pair<int, int>> pairs; void findans(int n, int p, int reps) { int max = 0, pos = 0, sum = 0; for (int i : graph[n]) { if (i == p) continue; sum += leaves[i]; if (leaves[i] > max) { max = leaves[i]; pos = i; } } int pairable = min(sum, (sum-max)*2); if (reps > pairable) { findans(pos, n, reps-pairable); leaves[pos] = sum-max; reps -= (reps-pairable); } /* PriorityQueue<int[]> pq = new PriorityQueue<>(new SortArr()); for (int i : graph[n]) { if (i == p) continue; pq.add(new int[] {i, leaves[i]}); } while (reps > 1) { int[] data1 = pq.poll(); int[] data2 = pq.poll(); int pos1 = findfirst(data1[0]); int pos2 = findfirst(data2[0]); upd(pos1, -1); upd(pos2, -1); pairs.add(new int[] {et[pos1]+1, et[pos2]+1}); if (data1[1] > 1) pq.add(new int[] {data1[0], data1[1]-1}); if (data2[1] > 1) pq.add(new int[] {data2[0], data2[1]-1}); reps -= 2; } if (reps == 1) { int[] data1 = pq.poll(); int pos1 = findfirst(data1[0]); upd(pos1, -1); pairs.add(new int[] {et[pos1]+1, n+1}); }*/ int maxleaves = 0; for (int i : graph[n]) { if (i==p) continue; maxleaves = std::max(maxleaves, leaves[i]); } vector<int> stack[maxleaves+1]; for (int i = 0; i < maxleaves+1; i++) { vector<int> temp; stack[i] = temp; } max = 0; int max2 = 0; for (int i : graph[n]) { if (i==p) continue; stack[leaves[i]].push_back(i); if (leaves[i] > max) { max2 = max; max = leaves[i]; } else if (leaves[i] > max2) max2 = leaves[i]; } while (reps > 1) { pair<int, int> data1{stack[max].back(), max}; stack[max].pop_back(); pair<int, int> data2{stack[max2].back(), max2}; stack[max2].pop_back(); int pos1 = findfirst(data1.first); int pos2 = findfirst(data2.first); upd(pos1, -1); upd(pos2, -1); pairs.push_back({et[pos1]+1, et[pos2]+1}); if (data1.second > 1) { stack[data1.second-1].push_back(data1.first); } if (data2.second > 1) { stack[data2.second-1].push_back(data2.first); } if (stack[max].size() == 0) max--; if (stack[max2].size() == 0) max2--; if (max2 == max && stack[max].size() == 1) max2--; reps -= 2; } if (reps == 1) { pair<int, int> data1{stack[max].back(), max}; stack[max].pop_back(); int pos1 = findfirst(data1.first); upd(pos1, -1); pairs.push_back({et[pos1]+1, n+1}); } } int main() { cin >> n; for (int i = 0; i < 500005; i++) { vector<int> temp; graph[i] = temp; } for (int i = 0; i < n-1; i++) { int a, b; cin >> a >> b; a--; b--; graph[a].push_back(b); graph[b].push_back(a); } for (int i = 0; i < 500005; i++) { if (graph[i].size() > 1) { start = i; break; } } leaffind(start, -1); findans(start, -1, leaves[start]); cout << (pairs.size()) << "\n"; for (pair<int, int> i : pairs) { cout << (i.first) << " " << (i.second) << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...