POJ 1849 Two(树的直径)

题意:给你一棵树,每条边都有权值,给你两个人去遍历这棵树,问将这棵树遍历完的最小代价是多少,给定两个人的起点,两个人不一定要回到起点。

求出所有的边的权值和,然后减去树的直径就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100005;
struct Edge
{
	int v,w;
	Edge* nxt;
}memo[N*2],*cur,*adj[N];

int dis[N];
void dfs(int u,int fa,int valu)
{
	for(Edge* it=adj[u];it;it=it->nxt)
	{
		int v=it->v,w=it->w;
		if(v==fa) continue;
		dfs(v,u,dis[v]=valu+w);
	}
}
void addEdge(int u,int v,int w)
{
	cur->v=v;	cur->w=w;
	cur->nxt=adj[u];
	adj[u]=cur++;
}
void init()
{
	cur=memo;
	memset(adj,0,sizeof(adj));
}
int main()
{
	int n,s;
	while(scanf("%d%d",&n,&s)!=EOF)
	{
		init();

		int sum=0,ind=1;
		for(int i=0;i<n-1;i++)
		{
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			sum+=2*w;
			addEdge(u,v,w);
			addEdge(v,u,w);
		}

		dfs(s,-1,dis[s]=0);
		for(int i=2;i<=n;i++) if(dis[ind]<dis[i]) ind=i;
		dfs(ind,-1,dis[ind]=0);
		for(int i=1;i<=n;i++) if(dis[ind]<dis[i]) ind=i;

		printf("%d\n",sum-dis[ind]);
	}
	return 0;
}


你可能感兴趣的:(POJ 1849 Two(树的直径))