日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

树的重心

發布時間:2024/9/3 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树的重心 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

樹的重心

說明:下面的定義等都是按照個人的理解所表述的,如有錯誤歡迎批評指出。

1.定義:

去掉該節點,最大的連通塊(子樹)的節點數目最少,則該節點點稱作該樹的重心。

2.性質:

  • 去掉一個重心后,生成的每個連通塊的節點數 <= 總節點數/2。
  • 重心可能不止一個,一棵樹最多有兩個重心,且相鄰。
  • 樹中所有點到重心的距離和最小。
  • 兩棵樹通過一條邊相連,新樹的重心一定在原來兩棵樹重心的連線上(不同樹的兩個重心所構成的路徑)。
  • 一棵樹添加或刪除一個節點,樹的重心最多移動一條邊的位置。

3.實例:

如下圖所示的一棵樹,可以很容易的看出,這棵樹的重心可以是2,也可以是3。去掉重心后,構成的最大連通塊節點數為3。比如,去掉2,得到的連通塊為:{1},{5},{3,4,6}。

4.題目和解題模板:

入門題目:POJ 1655,POJ 3107。
用樹形dp來求解重心

#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 5e4+5; struct Edge {int from;int to;int next; } edge[N<<1]; int head[N],id; /* dp[i]:存去掉i節點,所構成最大連通塊的節點數目 siz[i]:存儲以i為根的子樹節點的數目 minx:去掉重心后,最大連通塊的節點數目具體是多少, 用于判斷哪些點可以是重心 */ int dp[N],siz[N]; int n,minx; void init2() {for(int i = 1; i <= n; i++){dp[i] = 0;siz[i] = 1;}minx = 1 << 30; } void init() {memset(head,-1,sizeof(head));id = 0; } inline void add_edge(int from,int to) {edge[id].from = from;edge[id].to = to;edge[id].next = head[from];head[from] = id++; }void dfs(int u,int fa) {for(int i = head[u]; ~i; i = edge[i].next){int to = edge[i].to;if(to != fa){dfs(to,u);siz[u] += siz[to];dp[u] = max(dp[u],siz[to]);}}dp[u] = max(dp[u],n-siz[u]);minx = min(minx,dp[u]);return; } int main() {scanf("%d",&n);init();for(int i = 1; i < n; i++){int x,y;scanf("%d%d",&x,&y);add_edge(x,y);add_edge(y,x);}init2();dfs(1,0);bool flag = true;for(int i = 1; i <= n; i++){if(dp[i] == minx){if(flag){printf("%d",i);flag = false;continue;}printf(" %d",i);}}puts("");return 0; } 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的树的重心的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。