题目链接:1960: 单源最大权路径
Description
有一棵由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
Source
2017年6月月赛-暨中南大学暑期集训选拔赛第二场
Author
xushu
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
const int N = 1e5+5;
int h[N];
struct node
{
int to, w;
int next;
int sum;
} fr, fin, edge[4*N];
int cnt;
void add(int u, int v, int w)
{
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = h[u];
h[u] = cnt++;
}
int vis[N];
int dfs(int s)
{
int Max = 0;
memset(vis, 0, sizeof(vis));
stack<node>Q;
fr.to = s;
fr.sum = 0;
Q.push(fr);
vis[s] = 1;
while(!Q.empty())
{
fr = Q.top();
Q.pop();
for(int i = h[fr.to]; ~i; i = edge[i].next)
{
if(!vis[edge[i].to])
{
fin.to = edge[i].to;
fin.sum = fr.sum+edge[i].w;
if(fin.sum > Max) Max = fin.sum;
Q.push(fin);
vis[fin.to] = 1;
}
}
}
return Max;
}
int main()
{
int t;
scanf("%d", &t);
for(int k = 0; k < t; k++)
{
int n, s, u, v, w;
scanf("%d%d", &n, &s);
cnt = 0;
memset(h, -1, sizeof(h));
for(int i = 1; i < n; i++)
{
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
printf("Case #%d: %d\n", k+1, dfs(s));
}
return 0;
}