CSU OJ1960
有一棵由N个结点构成的树,每一条边上都有其对应的权值。现在给定起点,求从该点出发的一条路径(至少有一条边)使得这条路径上的权值之和最大,并输出这个最大值。
Input
第一行一个正整数T,代表数据组数。每组数据第一行两个正整数n(2<=n<=10^5),s(1<=s<=n),分别表示树结点数目以及给定的起点,点的编号从1至N。接下来M行,每行三个整数x,y,z,(1<=x,y<=n,|z|<=1000),代表编号为x和y的点之间有一条权值为z的双向边。
Output
每组数据输出一行,即所找到路径的最大权值(格式参见样例)。
Sample Input
2 3 1 1 2 10 1 3 5 5 5 1 5 70 4 3 100 5 3 -10 2 5 60
Sample Output
Case #1: 10 Case #2: 90
Hint
#include<cstdio> #include<algorithm> #include<vector> #include<cstring> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 100005; bool vis[maxn]; int ans; struct node { int v, w; node(int vv,int ww) : v(vv),w(ww) { } }; vector<node> edge[maxn]; void dfs(int u, int sum) { vis[u] = 1; for (int i = 0; i<edge[u].size(); i++) { if (!vis[edge[u][i].v]) dfs(edge[u][i].v, sum + edge[u][i].w); } ans = max(sum, ans); } int main() { int T, n, s, x, y, z, cae = 1; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &s); for (int i = 1; i <= n; i++) edge[i].clear(); for (int i = 1; i <= n - 1; i++) { scanf("%d%d%d", &x, &y, &z); edge[x].push_back((node) { y, z }); edge[y].push_back((node) { x, z }); } memset(vis, 0, sizeof(vis)); ans = -INF; dfs(s, 0); printf("Case #%d: %d\n", cae++, ans); } return 0; }