0w1

IOICJ 92 Double path tree ( Ad hoc, Timestamp )

Problem Description:
Given a tree, you want to do the least amount of operations to assert that for any two distinct nodes, there are at least two distinct simple paths that connect them.

Constraints:
1≤T≤300
3≤n≤1e5
1≤xi,yi≤n
A valid tree is given
Input file is less than 10 MB

Sample Input:
2
3
1 2
2 3
5
1 2
1 3
2 4
2 5

Sample Output:
1
1 3
2
4 5
4 3

Solution:
Consider extending the tree out so that no edges intersect. Imagine that all the leaves form somewhat a circle. Join every leaf with the leaf that is half the number of leaves away clockwise.

const int MAXN = ( int ) 1e5;

int N;
vvi G;
int ROOT;

void init(){
  cin >> N;
  G = vvi( N );
  for( int i = 0; i < N - 1; ++i ){
    int u, v; cin >> u >> v; --u, --v;
    G[ u ].emplace_back( v );
    G[ v ].emplace_back( u );
  }
  for( int i = 0; i < N; ++i ){
    if( G[ i ].size() > 1 ){
      ROOT = i;
      break;
    }
  }
}

int TS;
int tin[ MAXN ];

void build_ts( int u, int fa ){
  tin[ u ] = ++TS;
  for( int v : G[ u ] ){
    if( v == fa ) continue;
    build_ts( v, u );
  }
}

void preprocess(){
  TS = 0;
  build_ts( ROOT, -1 );
}

bool cmp( int a, int b ){
  return tin[ a ] < tin[ b ];
}

void solve(){
  vi leaf;
  for( int i = 0; i < N; ++i ){
    if( G[ i ].size() > 1 ) continue;
    leaf.emplace_back( i );
  }
  sort( leaf.begin(), leaf.end(), cmp );
  cout << ( leaf.size() + 1 ) / 2 << endl;
  for( int i = 0; i < leaf.size() / 2; ++i ){
    cout << leaf[ i ] + 1 << " " << leaf[ leaf.size() / 2 + i ] + 1 << endl;
  }
  if( leaf.size() & 1 ){
    cout << leaf.back() + 1 << " " << leaf[ leaf.size() / 2 ] + 1 << endl;
  }
}