程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj1655 Balancing Act 求樹的重心

poj1655 Balancing Act 求樹的重心

編輯:C++入門知識

poj1655 Balancing Act 求樹的重心


 

 

Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9072   Accepted: 3765

 

Description

Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created by deleting that node from T.
For example, consider the tree:
\

Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two.

For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.

Input

The first line of input contains a single integer t (1 <= t <= 20), the number of test cases. The first line of each test case contains an integer N (1 <= N <= 20,000), the number of congruence. The next N-1 lines each contains two space-separated node numbers that are the endpoints of an edge in the tree. No edge will be listed twice, and all edges will be listed.

Output

For each test case, print a line containing two integers, the number of the node with minimum balance and the balance of that node.

Sample Input

1
7
2 6
1 2
1 4
4 5
3 7
3 1

Sample Output

1 2

Source

POJ Monthly--2004.05.15 IOI 2003 sample task

求樹的重心!!

樹的重心性質是以該點為根的有根樹最大子樹的結點數最少,也就是讓這樹更加平衡,容易知道這樣所有的子樹的大小都不會超過整個樹大小的一半,所以在樹分治時防止樹退化成鏈很有用。。

求樹的重心做法是dfs簡單的樹dp就行。設son[i]表示以i為根的子樹的結點數(包括i,葉子結點就是1),那麼son[i]就+=sum(son[j])...然後求以i為根的最大結點數就是max(son[j],n-son[i]),n-son[i]是i的上方結點的個數。

關於樹的重心一些性質:http://fanhq666.blog.163.com/blog/static/81943426201172472943638/

代碼:

 

/**
 * @author neko01
 */
//#pragma comment(linker, /STACK:102400000,102400000)
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
using namespace std;
typedef long long LL;
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define clr(a) memset(a,0,sizeof a)
#define clr1(a) memset(a,-1,sizeof a)
#define dbg(a) printf(%d
,a)
typedef pair pp;
const double eps=1e-9;
const double pi=acos(-1.0);
const int INF=0x3f3f3f3f;
const LL inf=(((LL)1)<<61)+5;
const int N=20005;
struct node{
    int to,next;
}e[N*2];
int head[N];
int son[N];  //son[i]表示以i為根的子樹節點個數包括i
int dp[N];   //dp[i]表示以i為根時的最大子樹節點數
int tot;
int n;
void init()
{
    tot=0;
    clr1(head);
}
void add(int u,int v)
{
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u,int pre)
{
    son[u]=1;
    dp[u]=0;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        if(v!=pre)
        {
            dfs(v,u);
            son[u]+=son[v];
            dp[u]=max(dp[u],son[v]);
        }
    }
    dp[u]=max(dp[u],n-son[u]);
}
int main()
{
    int t;
    scanf(%d,&t);
    while(t--)
    {
        scanf(%d,&n);
        init();
        for(int i=1;i

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved