이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |