列表

详情


NC22618. 小A与欧拉路

描述

小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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 452ms, 内存消耗: 41672K, 提交时间: 2019-07-03 22:00:54

#include <bits/stdc++.h>
using namespace std;
vector <pair <int ,int > > a[800020];
int n;
long long ans=0;
long long d[800020];
bool v[800020];
void dp(int x){
	v[x]=1;
		for(int j=0;j<a[x].size();j++){
			int y=a[x][j].first;
			if(v[y]){
				continue;
			}
			dp(y);
			ans=max(ans,d[x]+d[y]+a[x][j].second);
			d[x]=max(d[x],d[y]+a[x][j].second);
		}
} 
int main(){
	cin>>n;
	long long cnt=0;
	for(int i=1;i<=n-1;i++){
		long long x,y,z;
		cin>>x>>y>>z;
		a[x].push_back(make_pair(y,z));
		a[y].push_back(make_pair(x,z));
		cnt+=z;
	}
	cnt*=2;
	dp(1);
	cout<<cnt-ans<<endl;
}

C++(clang++11) 解法, 执行用时: 158ms, 内存消耗: 24552K, 提交时间: 2020-11-03 17:06:56

#include<bits/stdc++.h>
using namespace std;
#define pi pair<int,int>
#define ll long long
const int N = 2e5 + 100;
vector<pi> G[N];int n,f[N],ans;
ll s = 0;
void dfs(int x,int fa) {
	for(auto e : G[x]) {
		int y = e.first,w = e.second;
		if(y == fa) continue;
		dfs(y,x);
		ans = max(f[x] + f[y] + w,ans);
		f[x] = max(f[x],f[y] + w);
	}
}
int main() {
	scanf("%d",&n);
	for(int a,b,c,i = 1;i < n;i++) {
		scanf("%d%d%d",&a,&b,&c);
		G[a].push_back(pi(b,c));
		G[b].push_back(pi(a,c));
		s += 2 * c;
	}
	dfs(1,0);printf("%lld\n",s - ans);
	return 0;
}

上一题