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;
}

  

 

posted @ 2018-07-29 20:30  StarHai  阅读(178)  评论(0编辑  收藏  举报