『樹的直徑』兩次dfs求樹的直徑

學習樹的直徑前提須知

樹的直徑 是一棵樹的某兩個最深的葉子節點的連線,多用於與圖論算法嵌套考算法

算法內容

競賽須要用到的點

一、很簡單的算法,不會單獨考,學習和熟練使用它的多種狀況學習

樹的直徑略講

很簡單,兩次dfsurl

至於爲何,能夠畫圖模擬一下,由於一次dfs必然會在一棵子樹或者根節點上,每次dfs必然找到一棵子樹的最深的葉子節點,那麼第二次dfs必然找到另一棵子樹的葉子節點,這兩點的惟一路徑就是整棵樹的直徑。由這個定理咱們又能夠獲得,樹的直徑不止一條spa

代碼以下(參考PT07Z - Longest path in a tree).net

//#define fre yes

#include <cstdio>
#include <cstring>

const int N = 10005;
int head[N << 1], to[N << 1], ver[N << 1];
int d[N];
bool Vis[N];

int tot;
void addedge(int x, int y) {
    ver[tot] = y;
    to[tot] = head[x];
    head[x] = tot++;
}

void dfs(int u) {
    Vis[u] = true;
    for (int i = head[u]; ~i; i = to[i]) {
        int v = ver[i];
        if(!Vis[v]) {
            d[v] = d[u] + 1;
            dfs(v);
        }
    }
}

int diameter(int n) {
    int st = 1, mx = -1e9;

    dfs(st);
    for (int i = 1; i <= n; i++) {
        if(d[i] > mx) {
            mx = d[i];
            st = i;
        }
    }

    memset(d, 0, sizeof(d));
    memset(Vis, false, sizeof(Vis));
    dfs(st);

    mx = -1e9;
    for (int i = 1; i <= n; i++) {
        if(d[i] > mx) {
            mx = d[i];
        }
    } return mx;
}

int main() {
    memset(head, -1, sizeof(head));
    static int n;
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        addedge(u, v);
        addedge(v, u);
    }

    printf("%d\n",diameter(n));
    return 0;
}

那麼也就會存在另外一個問題,讓你輸出你找的兩個節點的最短路徑code

挺智障的問題,能夠在更新完後獲得兩個節點來搞,也能夠在更新時來搞 前者時間消耗多一點,後者空間消耗多一下 看本身喜愛 這裏就不放代碼了get

相關文章
相關標籤/搜索