Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define sc( x ) scanf( "%d" , &x )
- #define REP( i , n ) for( int i = 0 ; i < n ; ++i )
- #define clr( t , val ) memset( t , val , sizeof( t ) )
- #define pb push_back
- #define all( v ) v.begin() , v.end()
- #define SZ( v ) ((int)(v).size())
- #define mp make_pair
- #define fi first
- #define se second
- #define N 100000
- #define LOGN 20
- #define M 500000
- #define test puts( "*************************test**********************" );
- typedef pair< int , int > pii;
- typedef vector< int > vi;
- typedef vector< vi > vvi;
- typedef vector< pii > vpii;
- struct bcc{
- int n , m , fin , timer, nbicomp , top;
- vi orig , dest , pila;//M
- vvi E;//N
- vi low , dfsn , part;//N
- vi ponte , bicomp;//M
- bcc(){}
- void clear( int nodes , int edges ){
- n = nodes , m = edges;
- orig = dest = pila = vi( m );
- E = vvi( n );
- low = dfsn = part = vi( n );
- ponte = bicomp = vi( m );
- }
- void add( int u , int v , int id ){
- orig[ id ] = u;
- dest[ id ] = v;
- E[ u ].pb( id );
- E[ v ].pb( id );
- }
- int dfsbcc( int u , int p = -1 ){
- low[ u ] = dfsn[ u ] = ++timer;
- int ch = 0;
- REP( i , SZ( E[ u ] ) ){
- int e = E[ u ][ i ] , v = (orig[ e ] == u? dest[ e ] : orig[ e ]);
- if( dfsn[ v ] == 0 ){
- pila[ top++ ] = e;
- dfsbcc( v , u );
- low[ u ] = min( low[ u ] , low[ v ] );
- ch++;
- if( low[ v ] >= dfsn[ u ] ){
- part[ u ] = 1;
- do{
- fin = pila[ --top ];
- bicomp[ fin ] = nbicomp;
- }while( fin != e );
- nbicomp++;
- }
- if( low[ v ] == dfsn[ v ] ) ponte[ e ] = 1;
- }else if( v != p && dfsn[ v ] < dfsn[ u ] ){
- pila[ top++ ] = e;
- low[ u ] = min( low[ u ] , dfsn[ v ] );
- }
- }
- return ch;
- }
- void doit(){
- REP( i , n ) part[ i ] = dfsn[ i ] = 0;
- REP( i , m ) ponte[ i ] = 0;
- top = nbicomp = timer = 0;
- REP( i , n ) if( dfsn[ i ] == 0 ) part[ i ] = dfsbcc( i ) >= 2;
- }
- }BCC;
- struct tree{
- vvi rmq;//logn n
- vi depth;
- vi vis;
- vvi G;
- vi in , out;
- int n , timer;
- tree(){}
- void clear( int nodes ){
- n = nodes;
- rmq = vvi( LOGN + 1 , vi( n , -1 ) );
- depth = vis = vi( n );
- in = out = vi( n );
- G = vvi( n );
- timer = 0;
- }
- void dfs( int u , int p = -1 ){
- in[ u ] = timer ++;
- vis[ u ] = 1;
- REP( i , SZ( G[ u ] ) ){
- int v = G[ u ][ i ];
- if( v != p && !vis[ v ] ){
- rmq[ 0 ][ v ] = u;
- depth[ v ] = depth[ u ] + 1;
- dfs( v , u );
- }
- }
- out[ u ] = timer ++;
- }
- void add( int u , int v ){
- G[ u ].pb( v );
- G[ v ].pb( u );
- }
- int LCA( int a , int b ){
- if( depth[ a ] > depth[ b ] ) swap( a , b );
- int dif = depth[ b ] - depth[ a ];
- for( int i = 0 ; i <= LOGN ; ++i ) if( dif & (1<<i) ) b = rmq[ i ][ b ];
- if( a == b ) return a;
- for( int k = LOGN ; k >= 0 ; --k )
- if( rmq[ k ][ a ] != rmq[ k ][ b ] ) a = rmq[ k ][ a ] , b = rmq[ k ][ b ];
- return rmq[ 0 ][ a ];
- }
- void doit(){
- dfs( 0 );
- for( int k = 1 ; k <= LOGN ; ++k )
- REP( i , n ) if( rmq[ k - 1 ][ i ] != -1 ) rmq[ k ][ i ] = rmq[ k - 1 ][ rmq[ k - 1 ][ i ] ];
- }
- bool isChild( int u , int v ){
- return in[ u ] <= in[ v ] && out[ v ] <= out[ u ];
- }
- bool isInPath2( int u , int v , int x ){
- return isChild( u , x ) && isChild( x , v );
- }
- bool isInPath( int u , int v , int x ){
- int lca = LCA( u , v );
- return isInPath2( lca , u , x ) || isInPath2( lca , v , x );
- }
- }TREE;
- struct graph{
- vi vis;
- vvi G;
- int n;
- vpii edges;
- graph(){}
- void clear( int nodes ){
- edges.clear();
- n = nodes;
- vis = vi( n );
- G = vvi( n );
- }
- void dfs( int u , int p = -1 ){
- vis[ u ] = 1;
- REP( i , SZ( G[ u ] ) ){
- int v = G[ u ][ i ];
- if( v != p && !vis[ v ] ){
- edges.pb( mp( u , v ) );
- dfs( v , u );
- }
- }
- }
- void add( int u , int v ){
- G[ u ].pb( v );
- G[ v ].pb( u );
- }
- void doit(){
- REP( i , n ) if( !vis[ i ] ) dfs( i );
- }
- }GRAPH;
- int main(){
- int n , m;
- while( sc( n ) == 1 ){
- sc( m );
- BCC.clear( n , m );
- GRAPH.clear( n );
- TREE.clear( n );
- map< pii , int > EDGES;
- REP( i , m ){
- int u , v ;
- sc( u ) , sc( v );
- u -- , v --;
- BCC.add( u , v , i );
- GRAPH.add( u , v );
- if( u > v ) swap( u , v );
- EDGES[ mp( u , v ) ] = i;
- }
- GRAPH.doit();
- BCC.doit();
- vpii &edges = GRAPH.edges;
- REP( i , SZ( edges ) ) TREE.add( edges[ i ].fi , edges[ i ].se );
- TREE.doit();
- int Q;
- sc( Q );
- REP( q , Q ){
- int op;
- sc( op );
- if( op == 1 ){
- int a , b , s , t;
- sc( a ) , sc( b ) , sc( s ) , sc( t );
- a -- , b -- , s -- , t --;
- if( s > t ) swap( s , t );
- int id = EDGES[ mp( s , t ) ];
- if( !BCC.ponte[ id ] ){
- puts( "ne" );
- continue;
- }
- if( TREE.isInPath( a , b , s ) && TREE.isInPath( a , b , t ) ) puts( "da" );
- else puts( "ne" );
- }else{
- int a , b , x;
- sc( a ) , sc( b ) , sc( x );
- a -- , b -- , x --;
- if( !BCC.part[ x ] ){
- puts( "ne" );
- continue;
- }
- if( TREE.isInPath( a , b , x ) ) puts( "da" );
- else puts( "ne" );
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment