题目链接:https://www.nowcoder.com/acm/contest/188/C
看似是一道最小生成树的题,实际上是一道思维题+暴搜,我们可以想一下,因为从一个结点出发要遍历所有的结点,所以必然是每条路径都要走两次,而只有一条路径只用走一次,所以我们只需要找出最长的一条路径让他只走一次就好了,所以最后的结果就是所有边的权值之和的二倍减去最长的一条路径。
AC代码:
#include <bits/stdc++.h>
#define maxn 50005
#define ll long long
using namespace std;
struct Node{
int to;
ll w;
int next;
}Edge[maxn << 1];
int head[maxn << 1];
int n,s,num;
ll maxx;
void init(){
memset(head,-1,sizeof(head));
num = 0;
}
void add(int u,int v,ll w){
Edge[num].to = v;
Edge[num].w = w;
Edge[num].next = head[u];
head[u] = num++;
}
void dfs(int x,int xx,ll step){
maxx = max(maxx, step);
for(int i=head[x];i!=-1;i=Edge[i].next){
if(Edge[i].to == xx)continue;
dfs(Edge[i].to, x, step + Edge[i].w);
}
}
int main()
{
init();
scanf("%d%d",&n,&s);
ll sum = 0;
for(int i=1;i<n;i++){
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
add(u,v,w);
add(v,u,w);
sum += w;
}
maxx = 0;
dfs(s, 0, 0);
cout<<sum * 2 - maxx<<endl;
return 0;
}