poj 3107 树重心
题目大意和思路同上题类似, 本题特殊点为其需要将多组满足要求的结果按递增全部输出。
解题代码:
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> using namespace std; #define MAX(a,b) (a)>(b)?(a):(b) #define MIN(a,b) (a)<(b)?(a):(b) const int N = 50010; int M[N], n; int head[N], idx; struct node{ int max, sum; }D[N]; struct Edge{ int v, next; }edge[N<<2]; void AddEdge(int a, int b) { edge[idx].v = b; edge[idx].next = head[a]; head[a] = idx++; edge[idx].v = a; edge[idx].next = head[b]; head[b] = idx++; } void input() { int a, b; //scanf("%d", &n); memset( head, 0xff, sizeof(head)); idx = 0; for(int i = 0; i < n-1; i++) { scanf("%d%d", &a,&b ); AddEdge(a, b); } } int dfs( int u, int pre ) { D[u].sum = 1; D[u].max = 0; for(int i = head[u]; ~i; i = edge[i].next ) { if( edge[i].v != pre ) { int t = dfs( edge[i].v, u ); D[u].sum += t; D[u].max = MAX( D[u].max, t ); } } return D[u].sum; } void solve() { dfs( 1, 0 ); int ans = 0x3fffffff, rt; for(int i = 1; i <= n; i++) { D[i].max = MAX( D[i].max, n-D[i].sum ); if( ans > D[i].max ) { rt = i; ans = D[i].max; } } bool flag = true; for(int i = 1; i <= n; i++) { if( D[i].max == ans ){ if( flag ) flag = false; else printf(" "); printf("%d", i); } } } int main() { ; while( scanf("%d", &n) != EOF) { input(); solve(); } return 0; }