有一棵由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 Input2 3 1 1 2 10 1 3 5 5 5 1 5 70 4 3 100 5 3 -10 2 5 60Sample Output
Case #1: 10 Case #2: 90
Hint
解题思路:这是一棵树,按照题目中所说的dfs遍历,也就可以得出来了
代码:
#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
#define maxx 100005
#define INF 0x3f3f3f3f
struct edge
{
int p;
int value;
edge(int aa,int bb)
{
p = aa;
value = bb;
}
};
vector<edge> E[maxx];
int dist[maxx];
bool vis[maxx];
int dfs(int h)
{
vis[h] = true;
for(int i = 0;i<E[h].size();i++)
{
int v = E[h][i].p;
int w = E[h][i].value;
if(vis[v])
continue;
dist[v] = dist[h]+w;
dfs(v);
}
}
int main()
{
int pointnum;
int be;
int t;
cin>>t;
int ca = 0;
while(t--)
{
ca++;
memset(dist,-INF,sizeof(dist));
memset(vis,false,sizeof(vis));
cin>>pointnum>>be;
for(int i = 0;i<=pointnum;i++)
E[i].clear();
int a,b,c;
for(int i = 0;i<pointnum-1;i++)
{
cin>>a>>b>>c;
E[a].push_back(edge(b,c));
E[b].push_back(edge(a,c));
}
dist[be] = 0;
dfs(be);
int ans = -INF;
for(int i = 1;i<=pointnum;i++)
ans = max(ans,dist[i]);
cout<<"Case #"<<ca<<": "<<ans<<endl;
}
}