The center of gravity of the topic tree

Outline of Solution: The total number of a selected node as the root node, provided DP [i] i is expressed in the root of the tree, dp [i] = j satisfy its child nodes D [j] and the sum plus 1 (root). Just look for the largest sub-tree node dfs process, the number of nodes and above it compare, you can find the center of gravity of the tree.

Title effect: For unrooted tree, to find such a point that point to the root tree rooted tree, the smallest sub-tree maximum (the maximum node after the node selecting its subtree) of the nodes.

https://blog.csdn.net/qq_41289920/article/details/83933631

https://blog.csdn.net/llzhh/article/details/78146548

https://blog.csdn.net/imzxww/article/details/81776219

template:

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<utility>
#include<stack>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<map>
using namespace std;
const int maxn = 5e4 + 5;
int head[maxn], to[maxn << 1], nx[maxn << 1], tot;
bool vst[maxn];
int Min = 0x3f3f3f3f, key;
int cnt[maxn], n; 
vector <int> vec; 
 
void add_edge(int u, int v) {
    to[tot] = v, nx[tot] = head[u], head[u] = tot++;
    swap(u, v);
    to[tot] = v, nx[tot] = head[u], head[u] = tot++;
}
 
int dfs(int u, int par) {
    cnt[u] = 1;
    int Max = 0;
    for(int i = head[u]; ~i; i = nx[i]) {
        int v = to[i];
        if(v != par) {
            cnt[u] += dfs(v, u);
            Max = max(Max, cnt[v]);
        }
    }
    if(Max < n - cnt[u])
        Max = n - cnt[u];
    if(Max < Min) {
        vec.clear();
        Min = Max;
        vec.push_back(u);
    } else if(Max == Min) {
        vec.push_back(u);
    }
    return cnt[u];
}
 
int main() {
    memset(head, -1, sizeof(head));
    tot = 0;
    Min = 0x3f3f3f3f;
    scanf("%d", &n);
    for(int i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        add_edge(u, v);
    }
    dfs(1, 1);
    sort(vec.begin(), vec.end());
    for(int i = 0; i < vec.size(); i++)
        printf("%d%c", vec[i], i + 1 == vec.size() ? '\n' : ' ');
return 0;
}
View Code

 

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define inf 1<<30
 
int n,dp[101],node,minans;    
vector<int> edge[101];
 
int dfs(int m,int fa)
{
    int maxnode=0;
    for(int i=0;i<edge[m].size();i++)
    {
        int tmp=Edge [m] [I];
         IF (tmp =! FA) 
        { 
            DP [m] + = DFS (tmp, m); 
            maxnode = max (maxnode, DP [tmp]);    // get the maximum sub-tree nodes 
        } 
    } 
    maxnode = max (maxnode, n--DP [m]);    // then the upper nodes compared 
    IF (maxnode < minans) 
    { 
        minans = maxnode; 
        Node = m; 
    } 
    return DP [m]; 
} 
 
int main () 
{ 
    the while (CIN >> n-) 
    { 
        for (int i=1;i<=n;i++) edge[i].clear();
        int a,b;
        for(int i=1;i<=n-1;i++)
        {
            cin>>a>>b;
            edge[a].push_back(b);
            edge[b].push_back(a);
        }
        for(int i=1;i<=n;i++)    //初始化都是1,即根节点本身 
        {
            dp[i]=1;
        }
        minans=inf;
        dfs(1,-1);
        cout<<minans<<" "<<node<<endl;
    }
    return 0;
} 

 

Weighted center of gravity of the tree: ---- explain edition: https://blog.csdn.net/qq_35781950/article/details/76854246

#include<bits/stdc++.h>//树的重心版本
using namespace std;
const int maxn=4e5+20;
struct Node{
       int to;
       int next;
}node[maxn];
int len;
int head[maxn];
void add(int a,int b){
     node[len].to=b;
     node[len].next=head[a];
     head[a]=len++;
}
int m;
bool vis[maxn];
int c_tre[maxn];
int num[maxn];
bool visit[maxn];//对应权重点
int k;
long long all=0;
int bkbk;
void Init(){
len=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
memset(c_tre,0,sizeof(c_tre));
memset(visit,false,sizeof(visit));
memset(num,0,sizeof(num));
all=0;
bkbk=0;
}
void dfs1(int x,int pre){
    if(visit[x]) {num[x]=1;}
    for(int i=head[x];i!=-1;i=node[i].next){
        int to=node[i].to;
        if(to==pre)continue;
        dfs1(to,x);
        num[x]+=num[to];
    }
    return ;//返回的这个num 带自身。
}
void dfs(int u,int fa)//求树的带权重心模板。
{
    int mx=k*2-num[u];
    for(int i=head[u]; i!=-1; i=node[i].next)
    {
        int v=node[i].to;
        if(v==fa) continue;
        mx=max(mx,num[v]);
    }
    if(mx<=k){
        bkbk=u;
        return ;
    }
    for(int i=head[u]; i!=-. 1 ; I = Node [I] .next) 
    { 
        int V = Node [I] .to;
         IF (FA == V) Continue ; 
        DFS (V, U); 
        IF (bkbk) return ; 
    } 
} 
void   dfs3 ( int C, int len) { // this search process is cumulative seek distance from the center of gravity of each point 
     VIS [C] = to true ;
      IF (Visit [C]) = All + len;
      for ( int I = head [C]; ! = I - . 1 ; I = Node [I] .next) {
           int to = Node [I] .to;
           IF(vis[to]) continue;
          dfs3(to,len+1);
     }
}
int main()
{   int t;
    int a,b;
    scanf("%d%d",&m,&k);
          Init();
          for(int i=0;i<2*k;i++){
             scanf("%d",&a);
             visit[a]=true;
          }
          //k*=2;
          for(int I = 0 ; I <M- . 1 ; I ++ ) { 
              Scanf ( " % D% D " , & A, & B); 
              the Add (B, A); 
              the Add (A, B); 
          } 
          DFS1 ( . 1 , - . 1 ); // record what weights. 
          DFS ( . 1 , - . 1 ); // calculate the weighted center of gravity. 
          = All 0 ; 
          Memset (VIS, to false , the sizeof (VIS)); 
          dfs3 (bkbk, 0 ); // calculate the weight of each point from the center of gravity and weight.
          cout<<all<<endl;
    return 0;
}

https://blog.csdn.net/q1093383371/article/details/52985375

#include <cstdio> 
#include <Vector> 
#include <the iostream> 
#include <Queue> 
#include <CString>
 #define MAXN 200005
 the using  namespace STD;
 // find the center of gravity of the tree 
int n-, popu [MAXN], TOT = 0 ; 
Vector < int > G [MAXN]; 

void the init () 
{ 
    Scanf ( " % D " , & n-); // represents the number of towns 
    int X, Y;
     for ( int I = . 1 ; I <n-; I ++) // n-1 edges form a tree represents
    {
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&popu[i]);//权值 
        tot+=popu[i];//权值总和 
    }
}

bool vis[maxn];
int fa[maxn],sum[maxn],dist[maxn],maxsum[maxn];
long long cost[maxn];

void DFS(int i)
{
    vis[i]=true;
    sum[i]=popu[i];
    cost[i]=0;
    for(int k=0;k<g[i].size();k++)
    {
        int j=g[i][k];
        if(vis[j]) continue;
        DFS(j);
        sum[i]+=sum[j];
        maxsum[i]=max(maxsum[i],sum[j]);
        cost[i]+=cost[j]+sum[j];
    }
    maxsum[i]=max(maxsum[i],tot-sum[i]);
}

void solve()
{
    init();
    DFS(1);
    int sum_min=tot,x;
    for(int i=1;i<=n;i++)
    {
        if(maxsum[i]<sum_min)
        {
            sum_min=maxsum[i];
            x=i;
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(maxsum[i]==sum_min)
        {
            printf("%d ",i);
        }
    }
    printf("\n");
    memset(vis,0,sizeof(vis));
    DFS(x);
    cout<<cost[x]<<endl;
}

int main()
{
    //freopen("in.txt","r",stdin);
    solve();
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/Aiahtwo/p/11518735.html