/***************************************************************\ *Author:Hu Wenbiao *Created Time: Tue 17 Aug 2010 04:54:15 PM CST *File Name: main.cpp *Description:树状dp。邻接表 \***************************************************************/ //*========================*Head File*========================*\\ #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> /*----------------------*Global Variable*----------------------*/ int dp[20010], first[20010], tot, t, N, a, b; struct Edge { int next, to; } edge[40010]; //*=======================*Main Program*=======================*// using namespace std; void insertedge(int a, int b) { //添加边(a,b),(b,a) edge[tot].to = b; edge[tot].next = first[a]; first[a] = tot++; edge[tot].to = a; edge[tot].next = first[b]; first[b] = tot++; } int tree_dp(int from, int now) { //现在结点now,它的父结点是from //sum记录now为根的子树的结点数,_max记录now各个子树最大结点数 int p = first[now], to; int _max = 0, sum = 1, tmp; while (p != -1) { to = edge[p].to; p = edge[p].next; if (to == from) continue; tmp = tree_dp(now, to); if (_max < tmp) _max = tmp; sum += tmp; } dp[now] = N - sum > _max ? N - sum : _max; return sum; } int main() { //freopen("input","r",stdin); scanf("%d", &t); while (t--) { memset(first, -1, sizeof(first)); tot = 0; scanf("%d", &N); for (int i = 1; i < N; i++) { scanf("%d%d", &a, &b); insertedge(a, b); } tree_dp(0, 1); int ans, _min = N; for (int i = 1; i <= N; i++) { if (dp[i] < _min) { _min = dp[i]; ans = i; } } printf("%d %d\n", ans, dp[ans]); } }
Source Code