제출 #647058

#제출 시각아이디문제언어결과실행 시간메모리
647058jasminMin-max tree (BOI18_minmaxtree)C++14
100 / 100
273 ms60480 KiB
#include<bits/stdc++.h> using namespace std; #define int long long struct bip_graph{ vector<vector<int> > adi; vector<int> m; vector<bool> vis; bip_graph(int n, int k){ adi.resize(n); m.resize(k, -1); vis.resize(n, false); } bool improve_matching(int v){ if(vis[v]) return false; vis[v]=true; for(auto u: adi[v]){ if(m[u]==-1 || improve_matching(m[u])){ m[u]=v; return true; } } return false; } void matching(int n){ vector<bool> done(n); for(auto e: m){ if(e!=-1) done[e]=true; } vis.assign(n, false); for(int i=0; i<n; i++){ if(!done[i] && improve_matching(i)){ vis.assign(n, false); } } } }; struct tree{ const int l=25; vector<vector<int> > adi; int t=0; vector<int> tin; vector<int> tout; vector<vector<int> > up; vector<vector<pair<int,int> > > mmax; vector<vector<pair<int,int> > > mmin; tree(int n){ adi.resize(n); tin.resize(n); tout.resize(n); up.resize(n, vector<int> (l, -1)); mmax.resize(n); mmin.resize(n); } void dfs_prepare(int v, int p){ tin[v]=t; t++; up[v][0]=p; for(int i=1; i<l; i++){ if(up[v][i-1]!=-1){ up[v][i]=up[up[v][i-1]][i-1]; } } for(auto u: adi[v]){ if(u==p) continue; dfs_prepare(u, v); } tout[v]=t; t++; } bool is_ancestor(int a, int b){ return tin[a]<=tin[b] && tout[b]<=tout[a]; } int lca(int a, int b){ if(is_ancestor(a, b)) return a; if(is_ancestor(b, a)) return b; for(int i=l-1; i>=0; i--){ if(up[a][i]!=-1 && !is_ancestor(up[a][i], b)){ a=up[a][i]; } } return up[a][0]; } void dfs(int v, int p, bip_graph& g, vector<int>& ans, set<pair<int,int> >& lb, set<pair<int,int> >& ub){ for(auto u: adi[v]){ if(u==p) continue; set<pair<int,int> >l; set<pair<int,int> >r; dfs(u, v, g, ans, l, r); if(l.size()>lb.size()) swap(l, lb); for(auto e: l) lb.insert(e); if(r.size()>ub.size()) swap(r, ub); for(auto e: r) ub.insert(e); } for(auto e: mmin[v]){ if(e.second>0){ lb.erase(e); } else{ e.second=-e.second; lb.insert(e); } } for(auto e: mmax[v]){ if(e.second>0){ ub.erase(e); } else{ e.second=-e.second; ub.insert(e); } } if(!lb.empty()){ auto lower=*prev(lb.end()); int ind=lower.second; ans[v]=lower.first; g.adi[ind].push_back(v); if(!g.vis[ind]){ g.m[v]=ind; g.vis[ind]=true; } } if(!ub.empty()){ auto upper=*ub.begin(); int ind=upper.second; g.adi[ind].push_back(v); if(ans[v]==-1) ans[v]=upper.first; if(!g.vis[ind] && g.m[v]==-1){ g.m[v]=ind; g.vis[ind]=true; } } if(ans[v]==-1) ans[v]=0; } }; signed main(){ ios_base::sync_with_stdio(false); cin.tie(0); int n; cin >> n; tree t(n); for(int i=0; i<n-1; i++){ int a, b; cin >> a >> b; a--; b--; t.adi[a].push_back(b); t.adi[b].push_back(a); } t.dfs_prepare(0, -1); int k; cin >> k; vector<int> val(k+1); bool minimum=false; for(int i=1; i<=k; i++){ char x; cin >> x; int a, b, c; cin >> a >> b >> c; a--; b--; int l=t.lca(a, b); val[i]=c; if(x=='M'){ t.mmax[a].push_back({c, -i}); t.mmax[b].push_back({c, -i}); t.mmax[l].push_back({c, i}); } else{ minimum=true; t.mmin[a].push_back({c, -i}); t.mmin[b].push_back({c, -i}); t.mmin[l].push_back({c, i}); } } bip_graph g(k+1, n); vector<int> ans(n, -1); set<pair<int,int> > lb; set<pair<int,int> > ub; t.dfs(0, -1, g, ans, lb, ub); if(minimum){ g.matching(k+1); for(int i=1; i<n; i++){ if(g.m[i]!=-1){ ans[i]=val[g.m[i]]; } } } for(int i=1; i<n; i++){ cout << i+1 << " " << t.up[i][0]+1 << " " << ans[i] << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...