이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC optimize("Ofast,unroll-loops")
#include "split.h"
#include <bits/stdc++.h>
#define pii pair<int,int>
#define x first
#define y second
#define N 100015
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
vector<int>g[N],leaf1,leaf2,res;
vector<pii>change,need_in;
set<int>tre[N];
int sz[N],n,a,b,c,mx[N],deg[N],fa[N];
int now1,now2,t=0,dfn[N],idx[2*N];
pii low[N];
bool vis[N];
void dfs(int p,int c){
vis[p]=1;
for (auto i:g[p]){
if (res[i]==c&&!vis[i])
dfs(i,c);
}
}
bool checker(){
int have[5]={0};
for (int i=1;i<=n;i++){
if (!vis[i]){
dfs(i,res[i]);
have[res[i]]++;
}
}
int h=(have[1]>1)+(have[2]>1)+(have[3]>1);
cout<<h<<'\n';
return h<=1;
}
void get_tree(int p,int lp){
fa[p]=lp; dfn[p]=++t; assert(dfn[p]<=200005);
idx[dfn[p]]=p;
low[p]=pii(dfn[p],p);
//cout<<"tree : "<<p-1<<" "<<lp-1<<'\n';
for (auto i:g[p]){
if (!dfn[i]){
tre[i].insert(p);
tre[p].insert(i);
get_tree(i,p);
low[p]=min(low[p],low[i]);
}
else if (i!=lp&&dfn[i]<dfn[p])
low[p]=min(low[p],pii(dfn[i],p));
}
}
void count_size(int p,int lp){
sz[p]=1; deg[p]=tre[p].size(); mx[p]=0;
for (auto i:tre[p]){
if (i!=lp){
count_size(i,p);
mx[p]=max(mx[p],sz[i]);
sz[p]+=sz[i];
}
}
}
void dfs1(int p,int lp){
res[p]=1; now1++;
if (tre[p].size()==1)
leaf1.push_back(p);
for (auto i:tre[p])
if (i!=lp&&!res[i])
dfs1(i,p);
}
void dfs2(int p,int lp){
res[p]=2; now2++;
if (tre[p].size()==1)
leaf2.push_back(p);
for (auto i:tre[p])
if (i!=lp&&!res[i])
dfs2(i,p);
}
bool check(int i){
change.clear(); need_in.clear();
if (sz[i]>=a&&sz[i]<=n-a)
return 1;
vector<pii>all;
for (auto j:tre[i]){
if (j!=fa[i]&&low[j].x<dfn[i])
all.push_back({sz[j],j});
}
sort(all.begin(),all.end());
int now=sz[i];
//cout<<"check "<<i<<" -> \n";
for (auto [s,j]:all){
now-=s;
change.push_back({i,j});
need_in.push_back(pii(low[j].y,idx[low[j].x]));
if (now>=a&&now<=n-a){
// cout<<i<<" find "<<now<<'\n';
for (auto [a,b]:change){
// cout<<"OUT "<<a<<" "<<b<<'\n';
tre[a].erase(b); deg[a]--;
tre[b].erase(a); deg[b]--;
}
sz[i]=now;
return 1;
}
}
return 0;
}
void solve(){
count_size(1,0);
int mid=0;
for (int i=1;i<=n;i++){
if (check(i)){
mid=i;
break;
}
}
if (mid==0) return;
//cout<<mid<<" size is : "<<sz[mid]<<'\n';
if (sz[mid]>=b){
dfs2(mid,fa[mid]);
for (auto [a,b]:need_in){
// cout<<"add "<<a<<' '<<b<<'\n';
tre[a].insert(b); deg[a]++;
tre[b].insert(a); deg[b]++;
}
for (auto i:tre[mid])
if (!res[i])
dfs1(i,mid);
}
else {
dfs1(mid,fa[mid]);
for (auto [a,b]:need_in){
// cout<<"add "<<a<<" "<<b<<'\n';
tre[a].insert(b); deg[a]++;
tre[b].insert(a); deg[b]++;
}
for (auto i:tre[mid])
if (!res[i])
dfs2(i,mid);
}
//for (int i=1;i<=n;i++)
/// cout<<res[i]<<" ";
//cout<<'\n';
while (now1>a){
//cout<<"have : "<<leaf1.size()<<'\n';
int out=leaf1.back(); leaf1.pop_back();
res[out]=3; now1--;
for (auto i:tre[out]){
deg[i]--;
if (deg[i]==1)
leaf1.push_back(i);
}
}
while (now2>b){
//cout<<"have : "<<leaf2.size()<<'\n';
int out=leaf2.back(); leaf2.pop_back();
res[out]=3; now2--;
for (auto i:tre[out]){
deg[i]--;
if (deg[i]==1)
leaf2.push_back(i);
}
}
}
vector<int> find_split(int _n, int A, int B, int C, vector<int> p, vector<int> q) {
n=_n;
vector<pii>s={{A,1},{B,2},{C,3}};
sort(s.begin(),s.end());
a=s[0].x; b=s[1].x; c=s[2].x;
for (int i=0;i<p.size();i++){
g[p[i]+1].push_back(q[i]+1);
g[q[i]+1].push_back(p[i]+1);
}
res.resize(n+1);
get_tree(1,0);
//cout<<"build tree OK\n";
solve();
//checker();
vector<int>ans; ans.resize(n,0);
if (res[1]==0) return ans;
for (int i=1;i<=n;i++)
ans[i-1]=(s[res[i]-1].y);
return ans;
}
/*
13 17 2 2 9
1 0
2 0
3 0
4 0
5 1
6 4
7 1
8 3
9 7
10 1
11 4
12 1
6 2
9 8
6 7
8 7
4 3
*/
컴파일 시 표준 에러 (stderr) 메시지
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:169:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
169 | for (int i=0;i<p.size();i++){
| ~^~~~~~~~~
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |