2196 Computer (樹的直徑)
ComputerTime Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 33989 Accepted Submission(s): 5236 Problem Description A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4. Input Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space. Output For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N). Sample Input 5 1 1 2 1 3 1 1 1 Sample Output 3 2 3 4 4 |
大意就是一棵樹,問某一個點能夠走的不重複點的最長的路徑是多少;
其實所有的樹都能化成一下圖形,而最中間的那個便叫做樹的直徑;
按照樹的直徑的特性。。你可以發現,任選一點開始bfs,他能到達的最遠的點,便是兩個直徑點的其中一個,在從這個點開始遍歷,最遠的點便是另一個直徑點了,這樣我們求得之後,任意一點得最長路徑,便是他與這兩個直徑點得距離得最大值;
得解。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 40010;
const int inf = 0x3f3f3f3f;
int n, fir_d[maxn], vis[maxn], sec_d[maxn];
int head[maxn],cnt;
struct fuck {
int u, v, ne, len;
}ed[maxn];
void add(int u, int v, int len) {
ed[cnt].u = u; ed[cnt].v = v;
ed[cnt].len = len; ed[cnt].ne = head[u]; head[u] = cnt++;
}
int dfs(int st,int d[]) {
for (int s = 1; s <= n; s++)
d[s] = inf;
memset(vis, 0, sizeof(vis));
d[st] = 0; vis[st] = 1;
queue<int>q; q.push(st);
int far = 0;
while (!q.empty()) {
int t = q.front(); q.pop(); vis[t] = 0;
far = max(d[t], far);
for (int s = head[t]; ~s; s = ed[s].ne) {
int v = ed[s].v;
if (d[v] > d[t] + ed[s].len) {
d[v] = d[t] + ed[s].len;
if (!vis[v]) {
q.push(v);
vis[v] = 1;
}
}
}
}
for (int s = 1; s <= n; s++)
if (d[s] == far)return s;
}
int main(){
while (~scanf("%d", &n)) {
memset(head, -1, sizeof(head)); cnt = 0;
for (int s = 2; s <= n; s++) {
int a, b;
scanf("%d%d", &a, &b);
add(a, s, b);add(s, a, b);
}
int st = dfs(1, fir_d);
int en = dfs(st, fir_d);
dfs(en, sec_d);
for (int s = 1; s <= n; s++)
printf("%d\n", max(fir_d[s], sec_d[s]));
}
}