Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4573 | Accepted: 1800 |
Description
Input
Output
Sample Input
1 7 2 6 1 2 1 4 4 5 3 7 3 1
Sample Output
1 2
Source
/* DFS树形DP搞定,minBal = min(minBal, max(n - num(i), num(k) for all i's son k)) for all nodes i 一开始采取的方案是:边输入边统计节点子孙数量,最后进行一遍线性扫描即可, 但是一直WA,后来分析了一下发现问题出在输入数据上的,输入数据并不一定是按照树形结构来的, 如果边输入边统计节点子孙数量那么很明显这就默认输入是按照树形结构来的,所以出错。后来改成 DFS就没有这个问题了 何为非树形结构输入:举个例子,对于树1->2->3,树形结构输入为1 2, 2 3;非树形结构输入为 1 2, 3 2这个特点决定了你不可能边输入边统计每个节点的子孙信息的 */ #include <iostream> #include <vector> #define maxv(a, b) ((a) >= (b) ? (a) : (b)) #define minv(a, b) ((a) <= (b) ? (a) : (b)) #define MAX_N 20010 using namespace std; struct node { vector<int> sons; }nodes[MAX_N + 5]; bool v[MAX_N + 5]; int n, minBal, minId; void init() { for(int i = 1; i <= n; i++) { v[i] = false; nodes[i].sons.clear(); } } int dfs(int curNode) { int curMax = INT_MIN, toId, total = 0; vector<int>::iterator iter = nodes[curNode].sons.begin(); for(; iter != nodes[curNode].sons.end(); iter++) { toId = *iter; if(!v[toId]) { v[toId] = true; int curNum = dfs(toId); curMax = maxv(curMax, curNum); total += curNum; } } total += 1; curMax = maxv(curMax, n - total); if(curMax < minBal) { minBal = curMax; minId = curNode; } return total; } int main() { int caseN, i, from, to; scanf("%d", &caseN); while(caseN--) { scanf("%d", &n); init(); for(i = 1; i < n; i++) { scanf("%d%d", &from, &to); nodes[from].sons.push_back(to); nodes[to].sons.push_back(from); } minBal = INT_MAX; dfs(1); printf("%d %d/n", minId, minBal); } return 0; }