The center of gravity and examples of the tree

The center of gravity of the tree: https://oi-wiki.org/graph/tree-centroid/

definition

For each point of the tree, which is calculated for all subtrees largest sub-tree nodes, the value is the minimum point of the center of gravity of the tree. (The largest sub-tree minimum)

nature

  1. When the tree is the root of gravity, the size of all the sub-tree does not exceed half the size of the whole tree.
  2. All the tree and the distance between the point of a point, and the distance to the center of gravity is minimal; if there are two focus, and so as to their distance.
  3. The two trees are connected by an edge to give a new tree, then the original path connecting the center of gravity of the two trees in the new center of gravity of the tree.
  4. Add or delete a leaf in a tree, then its center of gravity to move up to a distance of one side only.

Seeking

Almost all tree algorithm based on dfs, traversing the entire tree of all points in the process of recording the number of nodes as the root of all the sub-tree, the tree dp, dp re-iterate the array.

 

Example 1: POJ1655

Meaning of the questions: Tree n points to find the center of gravity, if there are two, a small number of output.

Thinking: arbitrary point (typically directly selected from 1) dfs root, traversing process where there are two variables, NUM [x] represents the number of the x-rooted subtree nodes (including itself), DP [x ] indicate if the x-focused delete the maximum number of nodes removed out of the sub-tree is the number? According to the definition of the center of gravity, the smallest maximum subtree.

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define inf 0x3f3f3f3f
const double pi=3.1415926;
using namespace std;

vector<int>a[20005];
int VIS [ 20005 ];
 int NUM [ 20005 ];
 int DP [ 20005 ];
 int T, n-, K; 


void DFS ( int X, int Last) /// this point, the parent node 
{ 

    DP [X] = 0 ; NUM [X] = . 1 ; /// NUM [X] represents a tree with itself as the root of the number of nodes, their count a subsequent cumulative contribution brought subtree. 
    the printf ( " Start DP [D%]% D NUM = [D%] D =% \ n- " , X, DP [X], X, NUM [X]);
     int RES = . 1 ; /// himself a node, a child node to see if there is no contribution to cut their own way back to the father 
    for (int i=0;i<a[x].size();i++)
    {
        int next=a[x][i];
        if(next==last)
            continue;
        dfs(next,x);
        dp[x]=max(dp[x],num[next]);
        num[x]+=num[next];
    }
    //printf("dp[%d]=%d\n",x,dp[x]);
    dp[x]=max(dp[x],n-num[x]);
    printf("结束 dp[%d]=%d num[%d]=%d \n",x,dp[x],x,num[x]);
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            a[i].clear();
            vis[i]=0;
            num[i]=0;
        }

        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x].push_back(y);
            a[y].push_back(x);
        }
        dfs(1,-1);
        int idx=1,cnt=dp[1];
        for(int i=2;i<=n;i++)
        {
            if(dp[i]<cnt)
                idx=i,cnt=dp[i];
        }
        printf("%d %d\n",idx,cnt);
    }
    return 0;
}
POJ1655

 

Example 2: https://ac.nowcoder.com/acm/contest/4479/C

The meaning of problems: n points of the tree, the root of a point as the root, the root depth of Deep the root is 0, the other nodes to the root depth of Deep I , and find the minimum depth of all points is.

Ideas: The nature of the article 2, dp tree to find the center of gravity, and again calculates the depth dfs.

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define inf 0x3f3f3f3f
const double pi=3.1415926;
using namespace std;

vector<int>a[1000005];
int n-, W = 0 ;;
 int VIS [ 1000005 ];
 int DP [ 1000005 ];
 int NUM [ 1000005 ]; 

void Find ( int X, int Last) /// this point, the parent node 
{ 

    DP [X] = 0 ; NUM [X] = . 1 ; /// NUM [X] represents a tree with itself as the root of the number of nodes, their count a subsequent cumulative contribution brought subtree. 
    int RES = . 1 ; /// himself a node, sub-node to see if there is no contribution to cut their way back to the father 
    for ( int I = 0 ; I <A [X] .size (); I ++ ) 
    {
        int next=a[x][i];
        if(next==last)
            continue;

        find(next,x);
        dp[x]=max(dp[x],num[next]);
        num[x]+=num[next];
    }
    dp[x]=max(dp[x],n-num[x]);
}

void dfs(int now,int deep){///计算深度和
    vis[now]=1;
    w=w+deep;
    for(int i=0;i<a[now].size();i++){
        if(vis[  a[now][i] ]==0){
            dfs(a[now][i],deep+1);
        }
    }
}


int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        a[x].push_back(y);
        a[y].push_back(x);
    }
    find(1,-1);
    int idx=1,cnt=dp[1];
    for(int i=2;i<=n;i++){///找重心
        if(dp[i]<cnt)
            idx=i,cnt=dp[i];
    }
    dfs(idx,0);
    printf("%d\n",w);
    return 0;
}
Cattle off OI14 popular C

 

Sky will not fall, and work hard to dream come true! - Xi greatly

Guess you like

Origin www.cnblogs.com/shoulinniao/p/12455654.html