http://162.105.81.212/JudgeOnline/problem?id=1655 测试了一下,第一个结点是否是第二个结点的父结点,返回TLE,验证我的猜测,不是。 只能用DFS构造树了,从叶子节点向根节点遍历,O(N) #include <iostream> #define MAXN 20010 using namespace std ; struct Graph { int next , vex ; }; Graph G[MAXN << 1] ; int par[MAXN] , child[MAXN] , sum[MAXN] , leaf[MAXN] , n , m , most[MAXN] , first[MAXN] ; bool visited[MAXN] ; void AddEdge (int v , int w , int &j) { G[j].vex = w ; G[j].next = first[v] ; first[v] = j ++ ; } void DFS (int v) { int i ; visited[v] = true ; for (i = first[v] ; i != -1 ; i = G[i].next) if (!visited[G[i].vex]) { par[G[i].vex] = v ; child[v] ++ ; DFS (G[i].vex) ; } } void Readin () { int i , v , w , j ; scanf ("%d" , &n) ; memset (child , 0 , sizeof (child)) ;//结点的子节点数 memset (par , -1 , sizeof (par)) ;//结点的父节点 memset (sum , 0 , sizeof (sum)) ;//结点所有直接,间接否认子节点数 memset (most , 0 , sizeof (most)) ;//所有子节点数中最多的一条 memset (first , -1 , sizeof (first)) ; memset (visited , false , sizeof (visited)) ; for (j = 0 , i = 1 ; i < n ; i ++) { scanf ("%d%d" , &v , &w) ; AddEdge (v , w , j) ; AddEdge (w , v , j) ; } DFS (1) ; for (i = 1 , m = 0 ; i <= n ; i ++) if (!child[i]) leaf[m ++] = i ;//叶子节点 } void Comp () { int i , j , ans ; for (i = 0 ; par[leaf[i]] != -1 ; i ++) { sum[par[leaf[i]]] += sum[leaf[i]] + 1 ; if (sum[leaf[i]] + 1 > most[par[leaf[i]]]) most[par[leaf[i]]] = sum[leaf[i]] + 1 ; if (-- child[par[leaf[i]]] == 0)//及时添加新增的叶子节点 leaf[m ++] = par[leaf[i]] ; } for (j = 0 , ans = n + 1 , i = 1 ; i <= n ; i ++) { if (n - sum[i] - 1 > most[i]) most[i] = n - sum[i] - 1 ; if (most[i] < ans) { ans = most[i] ; j = i ; } } printf ("%d %d/n" , j , most[j]) ; } int main () { int T ; scanf ("%d" , &T) ; while (T --) { Readin () ; Comp () ; } return 0 ; }