對於樹上的每乙個點,計算其所有子樹中最大的子樹節點數,這個值最小的點就是這棵樹的重心
以樹的重心為根時,所有子樹的大小都不超過整棵樹大小的一半一棵樹最多有兩個重心樹中所有點到某個點的距離和中,到重心的距離和是最小的;如果有兩個重心,那麼到它們的距離和一樣
在一棵樹上新增或刪除乙個葉子,那麼它的重心最多隻移動一條邊的距離把兩棵樹通過一條邊相連得到一棵新的樹,那麼新的樹的重心在連線原來兩棵樹的重心的路徑上
直接用定義求
inline
void
dfs(
int now,
int fa)
dp[now]
=max
(dp[now]
,n-dp[now]);
if(dp[now]
) ans=now;
}
用性質求(所有其他點到這個點的最短距離和)
inline
void
dfs1
(int now,
int fa,
int deep)
}inline
void
dfs2
(int now,
int fa)
參考:
圖中所有最短路徑的最大值
兩次dfs
const
int n =
10009
;vi adj[n]
;int d[n]
, c;
int n;
#define v (*it)
void
dfs(
int u)
}#undef v
intmain()
d[0]
=1,dfs(0
);rst(d)
, d[c]=1
,dfs
(c),
ot(d[c]-1
);}
樹形dp
#include
#include
using
namespace std;
const
int n =
int(
1e4)+9
;vector<
int> adj[n]
;int n, d;
intdfs
(int u =1,
int p =-1
) d =
max(d, d1 + d2)
;return d1;
}int
main()
dfs();
cout << d << endl;
}
樹的簡單問題
給定一顆樹,輸出樹的根root,孩子最多的結點max以及他的孩子。第一行 n 結點個數 100 m 邊樹 100 以下m行 每行倆個結點x和y,表示y是x的孩子 x,y 1000 第一行 樹根root。第二行 孩子最多的結點max。第三行 max的孩子。8 74 1 4 21 3 1 52 6 2 ...
線段樹 簡單的整數問題2
給定乙個長度為n的數列a,以及m條指令,每條指令可能是以下兩種之一 1 c l r d 表示把 a l a l 1 a r 都加上 d。2 q l r 表示詢問 數列中第 l r 個數的和。對於每個詢問,輸出乙個整數表示答案。輸入格式 第一行兩個整數n,m。第二行n個整數a i 接下來m行表示m條指...
簡單字典樹題目總結
關於字典樹請見 字典樹 trie 以下是我最近做的一些關於字典樹的題目,是hdu的一些經典題。hdu1251 統計難題 最簡單的字典樹題,對於字典中的字串插入後依次回答詢問子串個數即可,模板即為此題。hdu1305 immediate decodability 這題要求的是對於乙個字典是否滿足其中任...