标签:答案 ges include syn lag def ios compute std
题目链接
转换一下问题就是求每个点的最大长度,容易想到树的直径,一个点的最大长度就是他到两个端点长度的最大值,那我们就可以跑3遍dfs,第一遍求出直径的一个点,第二遍求出每个点到这个点的最大距离,第三遍利用第二遍求得的直径的另一点,反向跑,答案就是两者的最大值
这题好像还可以用点分治或者两遍dfs 我不会
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;
const int maxn = 1e4+7;
int head[maxn<<1], edgecnt, dis[maxn], ans[maxn];
struct Node {
int u, v, w, nex;
} edges[maxn<<1];
void addedge(int u, int v, int w) {
edges[edgecnt] = Node{u, v, w, head[u]};
head[u] = edgecnt++;
edges[edgecnt] = Node{v, u, w, head[v]};
head[v] = edgecnt++;
}
void dfs(int u, int fa) {
for(int i = head[u]; i != -1; i = edges[i].nex) {
int v = edges[i].v, w = edges[i].w;
if(v == fa) continue;
dis[v] = max(dis[u]+w, dis[v]);
dfs(v, u);
}
}
void run_case() {
int n;
while(cin >> n) {
memset(head, -1, sizeof(head));
edgecnt = 0;
for(int i = 2; i <= n; ++i) {
int v, w;
cin >> v >> w;
addedge(i, v, w);
}
memset(dis, 0, sizeof(dis));
dfs(1, -1);
int s, k = -1;
for(int i = 1; i <= n; ++i)
if(dis[i] > k) {
k = dis[i];
s = i;
}
memset(dis, 0, sizeof(dis));
dfs(s, -1);
k = -1;
for(int i = 1; i <= n; ++i) {
if(dis[i] > k) {
k = dis[i];
s = i;
}
ans[i] = dis[i];
}
k = -1;
memset(dis, 0, sizeof(dis));
dfs(s, -1);
for(int i = 1; i <= n; ++i)
cout << max(ans[i], dis[i]) << "\n";
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(10);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}
标签:答案 ges include syn lag def ios compute std
原文地址:https://www.cnblogs.com/GRedComeT/p/12369413.html