zoukankan      html  css  js  c++  java
  • CF1228F One Node is Gone

    题目链接

    问题分析

    这题感觉就是有很多种方法,然后一种都写不明白……

    首先分为3种情况:

    • 删了根节点下的一个节点,对应两个答案;
    • 删了一个叶节点,对应一个答案;
    • 删了一个其他节点,对应一个答案。

    可以从叶子向上一层一层处理。第一个情况比较好判断;剩下两种情况通过对应节点儿子的个数来判断。注意第二种情况叶节点最大深度差只能是1,其他的点不能有深度差(毕竟是完全二叉树)。

    面向数据编程

    参考程序

    #include <bits/stdc++.h>
    //#include <unistd.h>
    using namespace std;
     
    const int Maxn = 131100;
    struct edge {
    	int To, Next;
    	edge() {}
    	edge( int _To, int _Next ) : To( _To ), Next( _Next ) {}
    };
    edge Edge[ Maxn << 1 ];
    int Start[ Maxn ], Used;
    inline void AddEdge( int x, int y ) {
    	Edge[ ++Used ] = edge( y, Start[ x ] );
    	Start[ x ] = Used;
    	return;
    }
    int deep, n;
    int Deg[ Maxn ], Dep[ Maxn ], Deep, Son[ Maxn ];
    int Rec[ Maxn ], Left, Vis[ Maxn ];
    int Ans[ 10 ];
     
    int main() {
    	scanf( "%d", &deep );
    	n = 1; for( int i = 1; i <= deep; ++i ) n *= 2; n -= 2;
    	memset( Deg, 0, sizeof( Deg ) );
    	for( int i = 1; i < n; ++i ) {
    		int x, y;
    		scanf( "%d%d", &x, &y );
    		AddEdge( x, y );
    		AddEdge( y, x );
    		++Deg[ x ]; ++Deg[ y ];
    	}
     
    	Left = n;
    	Deep = 1;
    	for( int i = 1; i <= n; ++i )
    		if( Deg[ i ] == 1 ) 
    			Dep[ i ] = Deep;
     
    	while( Left > 1 ) {
    		//printf( "========================================
    " );
    		//printf( "Deg B:
    " );
    		//for( int i = 1; i <= n; ++i ) printf( "%d ", Deg[ i ] );
    		//printf( "
    " );
    		Rec[ 0 ] = 0;
    		for( int i = 1; i <= n; ++i ) 
    			if( Deg[ i ] == 1 ) {
    				Rec[ ++Rec[ 0 ] ] = i;
    				if( Son[ i ] != 3 && Dep[ i ] != Deep ) {
    					printf( "0
    " );
    					return 0;
    				}
    				if( Son[ i ] == 3 && Dep[ i ] + 1 != Deep ) {
    					printf( "0
    " );
    					return 0;
    				}
    				if( Son[ i ] != 2 && Son[ i ] != 0 ) {
    					if( Ans[ 0 ] ) {
    						printf( "0
    " );
    						return 0;
    					}
    					Ans[ ++Ans[ 0 ] ] = i;
    				}
    			}
    		//printf( "Rec %d
    ", Rec[ 0 ] );
    		//for( int i = 1; i <= Rec[ 0 ]; ++i ) printf( "%d ", Rec[ i ] );
    		//printf( "
    " );
     
    		if( Rec[ 0 ] == 2 && Left == 2 ) {
    			if( Ans[ 0 ] ) {
    				printf( "0
    " );
    				return 0;
    			}
    			printf( "2
    %d %d
    ", Rec[ 1 ], Rec[ 2 ] );
    			return 0;
    		}
    		
    		for( int i = 1; i <= Rec[ 0 ]; ++i )
    			Vis[ Rec[ i ] ] = 1;
     
    		for( int i = 1; i <= Rec[ 0 ]; ++i ) {
    			int u = Rec[ i ];
    			for( int t = Start[ u ]; t; t = Edge[ t ].Next ) {
    				int v = Edge[ t ].To;
    				if( Vis[ v ] ) continue;
    				--Deg[ u ]; --Deg[ v ];
    				++Son[ v ];
    				if( Dep[ v ] == 0 ) Dep[ v ] = Deep + 1;
    			}
    		}
    		
    		Left -= Rec[ 0 ];
    		++Deep;
    		//printf( "Deg A:
    " );
    		//for( int i = 1; i <= n; ++i ) printf( "%d ", Deg[ i ] );
    		//printf( "
    " );
    		//printf( "Left = %d
    ", Left );
    		//printf( "Son:
    " );
    		//for( int i = 1; i <= n; ++i ) printf( "%d ", Son[ i ] );
    		//printf( "
    " );
    		//printf( "Ans = %d
    ", Ans[ 0 ] );
    		//sleep( 3 );
    	}
     
    	printf( "1
    %d
    ", Ans[ 1 ] );
     
    	return 0;
    }
    
    
    
  • 相关阅读:
    B Graph(异或MST)
    G. Xor-MST(边权为俩点值的异或值,求MST)
    H Harmony Pairs(找(大小)和(位数和大小)逆序的点对,数位dp)
    hdu6787(根据喜欢程度分配得最大总价值,最大费用最大流)
    Codeforces Global Round 2
    2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛)
    Java EE学习笔记(九)
    Java EE学习笔记(八)
    Codeforces Round #549 (Div. 2)
    Codeforces Round #550 (Div. 3)
  • 原文地址:https://www.cnblogs.com/chy-2003/p/11617540.html
Copyright © 2011-2022 走看看