D. Eternal Victory(思维+树dfs)

https://codeforces.com/problemset/problem/61/D


题意:树上有边权,要求经过所有点,使得总边权最小。

思路:通过模拟可以发现,不管怎么走,有很多的路是要走两遍的,而且可以发现不管怎么走总会有一条从根节点出发到某个叶子节点结束的只经过一次边的路径。

那dfs找出这个最长的走一次的路径,答案就是全部边权总和*2-这个最长。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL ans,sum;
bool vis[maxn];
struct P{
   LL to,w;
};
vector<P>g[maxn]; 
void dfs(LL u,LL fa,LL val)
{
	vis[u]=true;
	for(LL i=0;i<g[u].size();i++)
	{
		LL v=g[u][i].to;
		if(v==fa||vis[v]==true) continue;
		vis[v]=true;
		LL w=g[u][i].w;
		ans=max(ans,val+w);
		dfs(v,u,val+w); 
	}
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  for(LL i=1;i<n;i++){
  	LL _x,_y,_w;cin>>_x>>_y>>_w;
  	sum+=_w;
  	g[_x].push_back({_y,_w});
  	g[_y].push_back({_x,_w});
  }
  sum=sum*2;
  //cout<<"sum="<<sum<<endl;
  dfs(1,0,0);
  cout<<sum-ans<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108625198