版权声明:欢迎转载,请注明此博客地址。 https://blog.csdn.net/Ever_glow/article/details/88052039
题目描述
小A给你了一棵树,对于这棵树上的每一条边,你都可以将它复制任意(可以为0)次(即在这条边连接的两个点之间再加一条边权相同的边),求所有可能新形成的图中欧拉路的最短长度
欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次
输入描述:
第一行一个数 n ,表示节点个数
接下来 n-1 行,每行三个整数 u,v,w,表示有一条 u 到 v 边权为 w 的无向边
保证数据是一棵树
输出描述:
一行一个整数,表示答案
示例1
输入
4 1 2 1 1 3 1 1 4 2
输出
5
说明
一种可能的方案为复制 <1,2,1> 这条边一次,欧拉路为4->1->2->1->3
就是将最长路之外的其他路走两遍,最长路只走一遍。
dfs求最长路,当前点的权值加上孩子中权值维护一个max值。
以任意点为根节点,遍历一遍树,得到结果。
代码实现:
/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
ll dis[N];
struct node{
ll next,w,v;
}p[N];
ll cnt = 0,head[N];
void add(ll u,ll v,ll w)
{
p[cnt].w = w;
p[cnt].v = v;
p[cnt].next = head[u];
head[u] = cnt++;
}
ll maxx;
void dfs(ll u,ll fa)
{
for(int i = head[u];~i;i = p[i].next)
{
if(p[i].v != fa)
{
dfs(p[i].v,u);
maxx = max(maxx,dis[u]+dis[p[i].v]+p[i].w);
dis[u] = max(dis[u],dis[p[i].v]+p[i].w);
}
}
}
int main()
{
ll n,i,j,k,u,v,w;
sl(n);
for(i = 0;i <= n;i++)
head[i] = -1;
ll ans = 0;
n--;
while(n--)
{
sl(u);sl(v);sl(w);
add(u,v,w);
add(v,u,w);
ans += w;
}
dfs(1,-1);
printf("%lld\n",ans*2-maxx);
return 0;
}