HDU 2196 Computer(樹的直徑)
阿新 • • 發佈:2019-01-31
輸出一棵樹上,每個點到最遠點的距離
思路:先搜兩遍找出樹的直徑,然後在從這兩點出發,每個點距離這兩點中距離大的就是最遠點距離
程式碼:
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; const int N = 50005; int n, m; struct Edge { int v, w; Edge() {} Edge(int v, int w) { this->v = v; this->w = w; } } edge[N * 2]; int head[N], nxt[N * 2], en; void addedge(int u, int v, int w) { edge[en] = Edge(v, w); nxt[en] = head[u]; head[u] = en++; } typedef long long ll; ll d[N]; queue<int> Q; int get(int s) { Q.push(s); memset(d, -1, sizeof(d)); d[s] = 0; int ans = s; while (!Q.empty()) { int u = Q.front(); Q.pop(); if (d[u] > d[ans]) ans = u; for (int i = head[u]; i + 1; i = nxt[i]) { int v = edge[i].v; int w = edge[i].w; if (d[v] != -1) continue; d[v] = d[u] + w; Q.push(v); } } return ans; } ll dp[N]; void gao(int s) { Q.push(s); memset(d, -1, sizeof(d)); d[s] = 0; while (!Q.empty()) { int u = Q.front(); Q.pop(); dp[u] = max(dp[u], d[u]); for (int i = head[u]; i + 1; i = nxt[i]) { int v = edge[i].v; int w = edge[i].w; if (d[v] != -1) continue; d[v] = d[u] + w; Q.push(v); } } } inline void scanf_(int &num)//無負數 { char in; while((in=getchar()) > '9' || in<'0') ; num=in-'0'; while(in=getchar(),in>='0'&&in<='9') num*=10,num+=in-'0'; } int main() { while (~scanf("%d", &n)) { en = 0; memset(head, -1, sizeof(head)); int x, y, z; for (int i = 2; i <= n; i++) { scanf_(y); scanf_(z); addedge(i, y, z); addedge(y, i, z); } int s = get(1); int e = get(s); memset(dp, 0, sizeof(dp)); gao(s); gao(e); for (int i = 1; i <= n; i++) printf("%I64d\n", dp[i]); } return 0; }