樹的中心問題是指:當給出 n 個結點與 n-1 條邊後,要選定乙個點作為整棵樹的根結點,使得從該點到每個葉結點的最長路徑最短。
樹的中心問題主要有兩種方法:dfs/bfs 進行搜尋、樹形 dp 進行狀態轉移
根據樹的中心問題的描述,顯然可以知道,樹的中心一定在樹的直徑上,而且趨於終點,否則它的最遠距離只會更遠。
因此,我們在利用 dfs 尋找樹的直徑的同時,對於直徑的兩個端點 st、ed,分別求其到每個點的距離 disst[i]、dised[i]
最後,對每個點進行更新,求最小距離
struct edge
edge(int to,int val,int next):to(to),val(val),next(next){}
} edge[n];
int n;
int head[n], tot;
int diameter,maxx, id;
int dis[n], disst[n], dised[n];
void addedge(int from, int to, int val)
void dfs(int x, int father)
dfs(y, x);
}}void calcdiameter()
int main()
calcdiameter();
int pos, minn = inf;
for (int i = 1; i <= n; ++i)
}printf("%d %d\n", pos, minn);
return 0;
}
利用樹形 dp 求解時,我們需要維護每個點 i 到所有葉結點的最長距離 up[i],從而去更新樹的中心。
由於採用樹形 dp 的方法,在求樹的直徑時已經知道如何維護每個結點 i 到其子樹的葉結點的最長距離 dis1[i] 與次長距離 dis2[i],那麼接下來就要考慮如何維護這個點向上的最遠距離 up[i]
依舊用 pos1[x] 表示 dis1[x] 在哪個點更新,pos2[x] 表示 dis2[x] 在哪個點更新,再求出樹的直徑後,再次進行一次 dfs 即可
struct edge
edge(int to,int val,int next):to(to),val(val),next(next){}
} edge[n];
int n;
int head[n], tot;
int dis1[n], dis2[n];//分別維護第i個點的最長鏈、次長鏈
int pos1[n],pos2[n];//分別維護dis1[i]、dis2[i]從哪個點更新
int up[n];//點i到所有葉結點的最遠距離
void addedge(int from, int to, int val)
void dfs(int x, int father)
else if (dis1[y] + val > dis2[x])
}}void dfscenter(int x, int father)
}int main()
dfs(1, 0);
dfscenter(1, 0);
int pos, minn = inf;
for (int i = 1; i <= n; i++)
}printf("%d %d", pos, minn);
return 0;
}
樹的中心問題,最常見的一種變型問題是:給出一棵樹 n 個點的點權與 n-1 條邊的邊權,求樹的最小代價的和,定義代價為樹中兩點距離乘以點的點權該問題是最常見的,一般資料規模較小,利用 floyd 演算法即可解決。
int n;
int g[n][n], node[n], sum[n];
int main()
//floyd記錄各點間的距離
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (g[i][j] > g[i][k] + g[k][j])
g[i][j] = g[i][k] + g[k][j];
//列舉求最小代價
int minn = inf;
for (int i = 1; i <= n; i++)
cout << minn << endl;
return 0;
}
資料結構 樹形結構 二叉樹 樹
深度 高度 層數 滿二叉樹 深度k上不能再新增葉結點 完全二叉樹 深度k上,第k層只刪除右邊的葉結點 不完全二叉樹 深度k上,第k層刪除了左邊的葉結點 排序二叉樹 左根右的數值從小到大,且不重複 最優二叉樹 哈夫曼樹 結點的度不為1,帶權 一般右子樹帶權 的路徑長度最短。二叉樹的順序儲存 採用虛擬結...
樹與二叉樹
樹是一類重要的非線性資料結構,是以分支關係定義的層次結構 定義 樹 tree 是n n 0 個結點的有限集t,其中 n 0時為空樹 n 0時,有且僅有乙個特定的結點,稱為樹的根 root 當n 1時,其餘結點可分為m m 0 個互不相交的有限集t1,t2,tm,其中每乙個集合本身又是一棵樹,稱為根的...
樹與二叉樹
建立 先序二叉樹,中序二叉樹,後序二叉樹。給定兩種遍歷序列 前序中序或後序中序 重塑二叉樹 遍歷 判斷乙個節點是否存在於二叉樹中 二叉樹的遍歷 先序,中序,後序 遞迴 非遞迴 層次遍歷 從上到下或從下到上列印 zigzag遍歷方式層次遍歷 二叉樹性質 二叉樹中葉子節點的個數 二叉樹第k層節點數目 二...