题意:链接:https://www.nowcoder.com/acm/contest/188/C
来源:牛客网
小w不会离散数学,所以她van的图论游戏是送分的
小w有一张n个点n-1条边的无向联通图,每个点编号为1~n,每条边都有一个长度
小w现在在点x上
她想知道从点x出发经过每个点至少一次,最少需要走多少路
思路:容易找出规律答案就是每条边的距离加起来乘以2减去最长的起点到其他点的最长的最短路。
看这个例子,从1出发,最优解就是13234而不是13432。容易看出最长的那条路只走了一遍,所以减去这条路。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll INF=0x3f3f3f3f;
const int maxn=50005*2;
using namespace std;
#define pa pair<int,int>
struct node
{
ll to,next,v;
};
node edge[maxn];
ll cnt=1,head[maxn];
ll dis[maxn];
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void addedge(ll u,ll v,ll w)
{
cnt++;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
edge[cnt].v=w;
}
void Dijkstra(int n,int now)
{
priority_queue<pa,vector<pa>,greater<pa> >q;
int i;
for (i=1;i<=n;i++)
dis[i]=INF*2;
dis[now]=0;
q.push(make_pair(0,now));
while (!q.empty())
{
now=q.top().second;
q.pop();
for (i=head[now];i;i=edge[i].next)
if (dis[now]+edge[i].v<dis[edge[i].to])
{
dis[edge[i].to]=dis[now]+edge[i].v;
q.push(make_pair(dis[edge[i].to],edge[i].to));
}
}
}
int main()
{
ll n,x,sum=0;
init();
cin>>n>>x;
for(int i=0;i<n-1;i++)
{
ll a,b,c;
cin>>a>>b>>c;
sum+=c;
addedge(a,b,c);
addedge(b,a,c);
}
sum*=2;
Dijkstra(n,x);
ll maxx=-1;
for(int i=1;i<=n;i++)
{
maxx=max(maxx,dis[i]);
}
cout<<sum-maxx<<endl;
return 0;
}