Submission #346728

#TimeUsernameProblemLanguageResultExecution timeMemory
346728evnNetwork (BOI15_net)C++14
100 / 100
1589 ms165092 KiB
#include <bits/stdc++.h> using namespace std; #define f first #define s second #define pb push_back #define mp make_pair #define sz(a) a.size() typedef long long ll; typedef pair<ll, ll> pii; #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; template<class T> using oset=tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; #define int long long vector<int> adj[500005]; bool isLeaf[500005]; set<int> leafs[500005]; vector<pii> links; int root = -1; int N; void dfs(int v, int p){ //cout << v << endl; assert(v >= 0 && v < N); for(int u : adj[v]){ if(u == p)continue; isLeaf[v] = false; dfs(u,v); } if(isLeaf[v]){ //cout << v << '\n'; leafs[v].insert(v); } vector<int> one; vector<int> two; map<int, int> imp; for(int u : adj[v]){ if(u == p)continue; if(leafs[u].size() == 1)one.pb(u); if(leafs[u].size() == 2)two.pb(u); if(v == root){ imp[u] = *leafs[u].begin(); } assert(leafs[u].size() == 1 || leafs[u].size() == 2); for(int x : leafs[u]){ leafs[v].insert(x); } } //cout << v << " " << leafs[v].size() << " " << (int)leafs[v].size()-2 << endl; //cout << v << " " << one.size() << " " << two.size() << "\n"; while((ll)leafs[v].size() - 2 >= 1LL){ //cout << "hi\n"; assert(leafs[v].size() == one.size() + 2 * two.size()); if(!two.empty()){ int tw = two[two.size()-1]; two.pop_back(); int o = -1; if(!two.empty()){ o = two[two.size()-1]; two.pop_back(); one.push_back(o); } else{ assert(!one.empty()); o = one[one.size()-1]; one.pop_back(); } one.push_back(tw); assert(o != -1 && tw != o); //cout << tw << " " << o << '\n'; //cout << *leafs[tw].begin() << " " << *leafs[o].begin() << '\n'; //cout << *leafs[tw].begin() << " " << *(--leafs[tw].end()) << '\n'; //link with back of one links.pb({*leafs[tw].begin(), *leafs[o].begin()}); leafs[v].erase(*leafs[tw].begin()); leafs[v].erase(*leafs[o].begin()); leafs[tw].erase(*leafs[tw].begin()); leafs[o].erase(*leafs[o].begin()); } else{ assert(one.size() >= 2); int ba = one[one.size()-1]; one.pop_back(); int ba2 = one[one.size()-1]; one.pop_back(); assert(ba != ba2); links.pb({*leafs[ba].begin(), *leafs[ba2].begin()}); leafs[v].erase(*leafs[ba].begin()); leafs[v].erase(*leafs[ba2].begin()); leafs[ba].erase(*leafs[ba].begin()); leafs[ba2].erase(*leafs[ba2].begin()); } } if(v == root){ //remove the final ones assert(p == -1); assert(leafs[v].size() == 1 || leafs[v].size() == 2 || leafs[v].size() == 0); if(leafs[v].size() == 0){ assert(one.size() == 0 && two.size() == 0); return; } else if(leafs[v].size() == 2){ assert(one.size() == 2 && two.size() == 0); assert(one[0] != one[1]); links.pb({*leafs[v].begin(), *(--leafs[v].end())}); } else{ //cout << *leafs[one[0]].begin() << '\n'; assert(one.size() == 1 && two.size() == 0); for(int u : adj[v]){ if(u != p && u != one[0]){ //cout << u << '\n'; //cout << *leafs[u].begin() << '\n' assert(imp[u] != *leafs[one[0]].begin()); links.pb({imp[u], *leafs[one[0]].begin()}); break; } } } } } int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N; for(int i =0;i < N-1; i++){ int a, b; cin >> a >> b; isLeaf[i]=true; a--; b--; adj[a].pb(b); adj[b].pb(a); } isLeaf[N-1]=true; for(int i = 0; i < N; i++){ if(adj[i].size() > 1){ root = i; isLeaf[root] = false; break; } } assert(root != -1); dfs(root, -1); int leafs = 0; for(int i = 0; i < N; i++){ if(isLeaf[i])leafs++; } cout << links.size() << '\n'; assert((ll)links.size() == (1LL * leafs+1)/2); for(int i = 0; i < (int)links.size(); i++){ assert(links[i].f != links[i].s); assert(links[i].f >= 0 && links[i].f < N); assert(links[i].s >= 0 && links[i].s < N); cout << links[i].f + 1 << " " << links[i].s + 1 << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...