UVa 10459 The Tree Root(樹)

題意:以同一棵樹以i爲根得到不同的最大深度。求最大深度最小的點和最大的點集。

思路:任取一點dfs一遍找到其最遠點,再從最遠點dfs一遍找到另一個最遠點。這樣所有點的最遠距離一定是到這兩個點之一。再反過來跑一遍dfs更新所有點的dist。這樣就得到了所有節點的爲根時的最大深度。

類似的題:

http://acm.hdu.edu.cn/showproblem.php?pid=2196

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
using namespace std;

typedef long long LL;
#define mem(a, n) memset(a, n, sizeof(a))
#define ALL(v) v.begin(), v.end()
#define si(a) scanf("%d", &a)
#define sii(a, b) scanf("%d%d", &a, &b)
#define siii(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pb push_back
#define eps 1e-8
const int inf = 0x3f3f3f3f, N = 1e4 + 5, MOD = 1e9 + 7;

int T, cas = 0;
int n, m;
int high, low, dist[N], Maxlen, ed;
vector<int> son[N];
vector<int> best, worst;

void dfs(int u, int fa, int deep) {
    if(deep > Maxlen) Maxlen = deep, ed = u;
    int sz = son[u].size();
    for(int i = 0; i < sz; i ++) {
        int v = son[u][i];
        if(v != fa) {
            dfs(v, u, deep + 1);
            dist[v] = max(dist[v], deep + 1);
        }
    }
}

void init() {
    Maxlen = 0;
    high = -1;
    low = inf;
    mem(dist, 0);
    best.clear(), worst.clear();
}

int main(){
#ifdef LOCAL
    freopen("/Users/apple/input.txt", "r", stdin);
 //	freopen("/Users/apple/out.txt", "w", stdout);
#endif
    
    while(si(n) != EOF) {
        int x; 
        init();
        best.clear(), worst.clear();
        for(int i = 1; i <= n; i ++) {
            si(m);
            son[i].clear();
            for(int j = 0; j < m; j ++) {
                si(x);
                son[i].pb(x);
            }
        }
        dfs(1, -1, 0);
        dfs(ed, -1, 0);
        dfs(ed, -1, 0);
        for(int i = 1; i <= n; i ++) high = max(high, dist[i]), low = min(low, dist[i]);
        for(int i = 1; i <= n; i ++) {
            // printf("%d's deep: %d\n", i, dist[i]);
            if(dist[i] == high) worst.pb(i);
            if(dist[i] == low) best.pb(i);
        }
        sort(ALL(best)), sort(ALL(worst));
        printf("Best Roots  :");
        for(int i = 0; i < best.size(); i ++) printf(" %d", best[i]); puts("");
        printf("Worst Roots :");
        for(int i = 0; i < worst.size(); i ++) printf(" %d", worst[i]); puts("");
    }
    
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章