제출 #727460

#제출 시각아이디문제언어결과실행 시간메모리
727460AdamGSNetwork (BOI15_net)C++17
100 / 100
541 ms68552 KiB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define rep(a, b) for(int a = 0; a < (b); ++a)
#define st first
#define nd second
#define pb push_back
#define all(a) a.begin(), a.end()
const int LIM=5e5+7;
vector<int>V[LIM];
vector<pair<int,int>>T;
int tr[4*LIM], pre[LIM], post[LIM], jaki[LIM], lpre, N=1, ost=-1;
void DFS(int x, int o) {
  ++lpre;
  jaki[lpre]=x;
  pre[x]=lpre;
  for(auto i : V[x]) if(i!=o) DFS(i, x);
  post[x]=lpre;
}
void upd(int v) {
  v+=N;
  while(v) {
    --tr[v];
    v/=2;
  }
}
int cnt(int l, int r) {
  l+=N; r+=N;
  int ans=tr[l];
  if(l!=r) ans+=tr[r];
  while(l/2!=r/2) {
    if(l%2==0) ans+=tr[l+1];
    if(r%2==1) ans+=tr[r-1];
    l/=2; r/=2;
  }
  return ans;
}
int zejdz(int v) {
  if(v>=N) {
    upd(v-N);
    return jaki[v-N];
  }
  if(tr[2*v]>0) return zejdz(2*v);
  return zejdz(2*v+1);
}
int znajdz(int l, int r) {
  l+=N; r+=N;
  vector<int>A, B;
  A.pb(l);
  if(l!=r) B.pb(r);
  while(l/2!=r/2) {
    if(l%2==0) A.pb(l+1);
    if(r%2==1) B.pb(r-1);
    l/=2; r/=2;
  }
  for(auto i : A) if(tr[i]>0) return zejdz(i);
  reverse(all(B));
  for(auto i : B) if(tr[i]>0) return zejdz(i);
  return -1;
}
void DFS2(int x, int o, vector<int>&P) {
  int p=cnt(pre[x], post[x]);
  bool t=false;
  for(auto i : V[x]) if(i!=o) {
    int z=cnt(pre[i], post[i]);
    if(2*z>p+P.size()) t=true;
  }
  if(t) {
    int b=P.size();
    for(auto i : V[x]) if(i!=o && 2*cnt(pre[i], post[i])<=p+b) {
      int a=znajdz(pre[i], post[i]);
      while(a!=-1) {
        P.pb(a);
        a=znajdz(pre[i], post[i]);
      }
    }
    for(auto i : V[x]) if(i!=o && cnt(pre[i], post[i])) DFS2(i, x, P);
    return;
  }
  priority_queue<pair<ll,ll>>q;
  if(P.size()) q.push({P.size(), LIM});
  for(auto i : V[x]) if(i!=o && cnt(pre[i], post[i])) q.push({cnt(pre[i], post[i]), i});
  while(q.size()>1) {
    auto a=q.top(); q.pop();
    auto b=q.top(); q.pop();
    --a.st;
    if(a.st) q.push(a);
    --b.st;
    if(b.st) q.push(b);
    int r, t;
    if(a.nd==LIM) {
      r=P.back(); P.pop_back();
    } else r=znajdz(pre[a.nd], post[a.nd]);
    if(b.nd==LIM) {
      t=P.back();
      P.pop_back();
    } else t=znajdz(pre[b.nd], post[b.nd]);
    T.pb({r, t});
  }
  if(q.size()) {
    int p=q.top().nd, z;
    if(p==LIM) z=P.back();
    else z=znajdz(0, N-1);
    ost=z;
  }
}
int main() {
  ios_base::sync_with_stdio(0); cin.tie(0);
  int n;
  cin >> n;
  while(N<=n) N*=2;
  rep(i, n-1) {
    int a, b;
    cin >> a >> b; --a; --b;
    V[a].pb(b);
    V[b].pb(a);
  }
  int r=0;
  rep(i, n) if(V[i].size()>1) r=i;
  DFS(r, r);
  rep(i, n) if(V[i].size()==1) tr[N+pre[i]]=1;
  for(int i=N-1; i; --i) tr[i]=tr[2*i]+tr[2*i+1];
  vector<int>P;
  DFS2(r, r, P);
  if(ost!=-1) T.pb({ost, r});
  cout << T.size() << '\n';
  for(auto i : T) cout << i.st+1 << " " << i.nd+1 << '\n';
}

컴파일 시 표준 에러 (stderr) 메시지

net.cpp: In function 'void DFS2(int, int, std::vector<int>&)':
net.cpp:67:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   67 |     if(2*z>p+P.size()) t=true;
      |        ~~~^~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...