Floyd演算法(計算最短路徑)

若把你比作歌發表於2024-05-30

[JLOI2009] 二叉樹問題

題目描述

如下圖所示的一棵二叉樹的深度、寬度及結點間距離分別為:

  • 深度:$4$
  • 寬度:$4$
  • 結點 8 和 6 之間的距離:$8$
  • 結點 7 和 6 之間的距離:$3$

其中寬度表示二叉樹上同一層最多的結點個數,節點 $u, v$ 之間的距離表示從 $u$$v$ 的最短有向路徑上向根節點的邊數的兩倍加上向葉節點的邊數。

給定一顆以 1 號結點為根的二叉樹,請求出其深度、寬度和兩個指定節點 $x, y$ 之間的距離。

輸入格式

第一行是一個整數,表示樹的結點個數 $n$
接下來 $n - 1$ 行,每行兩個整數 $u, v$,表示樹上存在一條連線 $u, v$ 的邊。
最後一行有兩個整數 $x, y$,表示求 $x, y$ 之間的距離。

輸出格式

輸出三行,每行一個整數,依次表示二叉樹的深度、寬度和 $x, y$ 之間的距離。

樣例 #1

樣例輸入 #1

10                                
1 2                            
1 3                            
2 4
2 5
3 6
3 7
5 8
5 9
6 10
8 6

樣例輸出 #1

4
4
8

提示

對於全部的測試點,保證 $1 \leq u, v, x, y \leq n \leq 100$,且給出的是一棵樹。

解題思路

求樹的深度,就是求節點到根節點的距離最大值。
求樹的寬度,就是求同一深度節點(到根節點距離相同)的數量最大值。

Floyd演算法

計算任意兩點的最短路徑

for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            graph[i][j] = MIN(graph[i][j], graph[i][k]+graph[k][j]);
        }
    }
}

計算透過k處,i節點到j節點的最短距離

AC程式碼

#include<bits/stdc++.h>
using namespace std;
#define MAX(a, b) ((a)<(b)?(b):(a))
#define MIN(a, b) ((a)<(b)?(a):(b))
int n;

int graph[100][100];

int main() {
    cin >> n;
    int u, v;
    memset(graph, 0, sizeof(graph));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i != j) graph[i][j] = INT_MAX/2;
        }
    }

    for (int i = 0; i < n-1; i++) {
        cin >> u >> v;
        graph[u][v] = 1;
        graph[v][u] = 2;
    }
    cin >> u >> v;
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                graph[i][j] = MIN(graph[i][j], graph[i][k]+graph[k][j]);
            }
        }
    }
    int depth = 0, width = 0, max = 0;
    int d[100] = {0};
    for (int i = 2; i <= n; i++) {
        depth = MAX(graph[1][i], depth);  // 列舉到根節點的深度
        d[graph[1][i]]++;  // 不同深度計數
    }
    for (int i = 1; i <= depth; i++) {
        width = MAX(d[i], width);  // 遍歷不同深度的節點數量,計算最大值
    }
    cout << depth+1 << endl;  // 根節點深度為1
    cout << width << endl;
    cout << graph[u][v] << endl;
}

相關文章