Submission #239516


Source Code Expand

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <functional>
#include <iterator>
#include <limits>
#include <numeric>
#include <utility>
#include <cmath>

using namespace std; using namespace placeholders;

using LL = long long;
using ULL = unsigned long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VS = vector<string>;
using SS = stringstream;
using PII = pair<int,int>;
using VPII = vector< pair<int,int> >;
template < typename T = int > using VT = vector<T>;
template < typename T = int > using VVT = VT< VT<T> >;
template < typename T = int > using LIM = numeric_limits<T>;

template < typename T > inline T fromString( const string &s ){ T res; istringstream iss( s ); iss >> res; return res; };
template < typename T > inline string toString( const T &a ){ ostringstream oss; oss << a; return oss.str(); };

#define REP( i, m, n ) for ( int i = (int)( m ); i < (int)( n ); ++i )
#define FOR( e, c ) for ( auto &e : c )
#define ALL( c ) (c).begin(), (c).end()
#define AALL( a, t ) (t*)a, (t*)a + sizeof( a ) / sizeof( t )
#define DRANGE( c, p ) (c).begin(), (c).begin() + p, (c).end()

#define PB( n ) push_back( n )
#define MP( a, b ) make_pair( ( a ), ( b ) )
#define EXIST( c, e ) ( (c).find( e ) != (c).end() )

#define fst first
#define snd second

#define DUMP( x ) cerr << #x << " = " << ( x ) << endl

class LowestCommonAncestor
{
private:
	const int N;
	std::vector< std::vector<int> > G;

	bool constructed = false;
	std::vector<int> depth_;
	std::vector< std::vector<int> > parent_;

public:
	LowestCommonAncestor( const int n ) : N( n ), G( N ), depth_( N ), parent_( N, std::vector<int>( 31, -1 ) )
	{
		return;
	}

	LowestCommonAncestor( const std::vector< std::vector<int> > &g ) : N( g.size() ), G( g ), depth_( N ), parent_( N, std::vector<int>( 31, -1 ) )
	{
		return;
	}

	void connect( const int u, const int v )
	{
		G[u].push_back( v );
		G[v].push_back( u );
		constructed = false;

		return;
	}

	int depth( const int u ) const
	{
		return depth_[u];
	}

	int solve( int u, int v )
	{
		if ( !constructed )
		{
			dfs( 0, -1, 0 );
			doubling();
			constructed = true;
		}

		if ( depth_[u] < depth_[v] )
		{
			swap( u, v );
		}

		{ // align depths
			int diff = depth_[u] - depth_[v];
			for ( int i = 30; 0 <= i; --i )
			{
				if ( diff & 1 << i )
				{
					u = parent_[u][i];
				}
			}
		}

		if ( u == v )
		{
			return u;
		}

		for ( int i = 30; 0 <= i; --i )
		{
			if ( parent_[u][i] != parent_[v][i] )
			{
				u = parent_[u][i];
				v = parent_[v][i];
			}
		}

		return parent_[u][0];
	}

private:
	void dfs( const int u, const int prev, const int d )
	{
		depth_[u] = d;
		parent_[u][0] = prev;

		for ( const int v : G[u] )
		{
			if ( v == prev )
			{
				continue;
			}

			dfs( v, u, d + 1 );
		}

		return;
	}

	void doubling()
	{
		for ( int i = 0; i < 30; ++i )
		{
			for ( int u = 0; u < N; ++u )
			{
				if ( parent_[u][i] != -1 )
				{
					parent_[u][ i + 1 ] = parent_[ parent_[u][i] ][i];
				}
			}
		}
		return;
	}
};



int main()
{
	cin.tie( 0 );
	ios::sync_with_stdio( false );

	int n;
	cin >> n;

	LowestCommonAncestor lca( n );
	REP( i, 0, n - 1 )
	{
		int a, b;
		cin >> a >> b;
		lca.connect( a - 1, b - 1 );
	}

	int q;
	cin >> q;

	REP( iteration, 0, q )
	{
		int a, b;
		cin >> a >> b;
		a--, b--;

		const int anc = lca.solve( a, b );

		cout << lca.depth( a ) + lca.depth( b ) - 2 * lca.depth( anc ) + 1 << endl;
	}

	return 0;
}

Submission Info

Submission Time
Task D - 閉路
User torus711
Language C++11 (GCC 4.8.1)
Score 100
Code Size 3757 Byte
Status AC
Exec Time 756 ms
Memory 26020 KB

Judge Result

Set Name Sample Subtask1 Subtask2
Score / Max Score 0 / 0 30 / 30 70 / 70
Status
AC × 3
AC × 12
AC × 27
Set Name Test Cases
Sample subtask0_sample01.txt, subtask0_sample02.txt, subtask0_sample03.txt
Subtask1 subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt
Subtask2 subtask0_sample01.txt, subtask0_sample02.txt, subtask0_sample03.txt, subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask2_01.txt, subtask2_02.txt, subtask2_03.txt, subtask2_04.txt, subtask2_05.txt, subtask2_06.txt, subtask2_07.txt, subtask2_08.txt, subtask2_09.txt, subtask2_10.txt, subtask2_11.txt, subtask2_12.txt
Case Name Status Exec Time Memory
subtask0_sample01.txt AC 25 ms 920 KB
subtask0_sample02.txt AC 25 ms 796 KB
subtask0_sample03.txt AC 27 ms 784 KB
subtask1_01.txt AC 221 ms 26020 KB
subtask1_02.txt AC 245 ms 25960 KB
subtask1_03.txt AC 25 ms 752 KB
subtask1_04.txt AC 31 ms 756 KB
subtask1_05.txt AC 25 ms 1044 KB
subtask1_06.txt AC 24 ms 1048 KB
subtask1_07.txt AC 253 ms 23072 KB
subtask1_08.txt AC 254 ms 23052 KB
subtask1_09.txt AC 274 ms 23068 KB
subtask1_10.txt AC 265 ms 23080 KB
subtask1_11.txt AC 265 ms 23072 KB
subtask1_12.txt AC 261 ms 23068 KB
subtask2_01.txt AC 513 ms 26020 KB
subtask2_02.txt AC 520 ms 25916 KB
subtask2_03.txt AC 295 ms 932 KB
subtask2_04.txt AC 313 ms 800 KB
subtask2_05.txt AC 324 ms 1000 KB
subtask2_06.txt AC 329 ms 1056 KB
subtask2_07.txt AC 654 ms 23076 KB
subtask2_08.txt AC 647 ms 23080 KB
subtask2_09.txt AC 681 ms 23072 KB
subtask2_10.txt AC 756 ms 23072 KB
subtask2_11.txt AC 711 ms 23076 KB
subtask2_12.txt AC 697 ms 23072 KB