因为是棵树 , 所以直接 dfs 就好了...
-------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define rep( i , n ) for( int i = 0 ; i < n ; i++ )
#define clr( x , c ) memset( x , c , sizeof( x ) )
using namespace std;
const int maxn = 10000 + 5;
struct edge {
int to;
edge* next;
};
edge* pt , EDGE[ maxn << 1 ];
edge* head[ maxn ];
void edge_init() {
pt = EDGE;
clr( head , 0 );
}
void add( int u , int v ) {
pt -> to = v;
pt -> next = head[ u ];
head[ u ] = pt++;
}
#define add_edge( u , v ) add( u , v ) , add( v , u )
int n;
int size[ maxn ] , Max;
bool ans[ maxn ];
void dfs( int x , int fa ) {
size[ x ] = 1;
for( edge* e = head[ x ] ; e ; e = e -> next ) {
int to = e -> to;
if( to == fa ) continue;
dfs( to , x );
size[ x ] += size[ to ];
if( size[ to ] > Max ) ans[ x ] = false;
}
if( n - size[ x ] > Max ) ans[ x ] =false;
}
int main() {
freopen( "test.in" , "r" , stdin );
edge_init();
clr( ans , -1 );
cin >> n;
rep( i , n - 1 ) {
int u , v;
scanf( "%d%d" , &u , &v );
u-- , v--;
add_edge( u , v );
}
Max = n >> 1;
dfs( 0 , -1 );
bool flag = false;
rep( i , n ) if( ans[ i ] ) {
printf( "%d\n" , i + 1 );
flag = true;
}
if( ! flag ) printf( "NONE\n" );
return 0;
}
-------------------------------------------------------------------------------------
3391: [Usaco2004 Dec]Tree Cutting网络破坏
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 80 Solved: 63
[Submit][Status][Discuss]
Description
约翰意识到贝茜建设网络花费了他巨额的经费,就把她解雇了.贝茜很愤怒,打算狠狠报
复.她打算破坏刚建成的约翰的网络. 约翰的网络是树形的,连接着N(1≤N≤10000)个牛棚.她打算切断某一个牛棚的电源,使和这个牛棚相连的所有电缆全部中断.之后,就会存在若干子网络.为保证破坏够大,每一个子网的牛棚数不得超过总牛棚数的一半,那哪些牛棚值得破坏呢?
Input
第1行:一个整数N.
第2到N+1行:每行输入两个整数,表示一条电缆的两个端点.
Output
按从小到大的顺序,输出所有值得破坏的牛棚.如果没有一个值得破坏,就输出“NONE”.
Sample Input
10
1 2
2 3
3 4
4 5
6 7
7 8
8 9
9 10
3 8
Sample Output
3
8
如果牛棚3或牛棚8被破坏,剩下的三个子网节点数将是5,2,2,没有超过5的.
来源信息