AtCoder Grand Contest 018--D题
2017-07-27 17:07
399 查看
D - Tree and Hamilton Path
Time limit : 2sec / Memory limit : 256MBScore : 1100 points
Problem Statement
There is a tree with N vertices,numbered 1 through N.
The i-th edge in this tree connects Vertices Ai and Bi and
has a length of Ci.
Joisino created a complete graph with N vertices.
The length of the edge connecting Vertices u and v in
this graph, is equal to the shortest distance between Vertices uand v in
the tree above.
Joisino would like to know the length of the longest Hamiltonian path (see Notes) in this complete graph. Find the length of that path.
Notes
A Hamiltonian path in a graph is a path in the graph that visits each vertex exactly once.Constraints
2≤N≤1051≤Ai<Bi≤N
The given graph is a tree.
1≤Ci≤108
All input values are integers.
Input
Input is given from Standard Input in the following format:N A1 B1 C1 A2 B2 C2 : AN−1 BN−1 CN−1
Output
Print the length of the longest Hamiltonian path in the complete graph created by Joisino.Sample Input 1
Copy5 1 2 5 3 4 7 2 3 3 2 5 2
Sample Output 1
Copy38
The length of the Hamiltonian path 5 → 3 → 1 → 4 → 2 is 5+8+15+10=38.
Since there is no Hamiltonian path with length 39 or greater in the graph, the answer is38.
Sample Input 2
Copy8 2 8 8 1 5 1 4 8 2 2 5 4 3 8 6 6 8 9 2 7 12
Sample Output 2
Copy132
题解:
case1:存在一条边,移除这条边后,树分成两个顶点数目相同的子树。如1-2-3-4-5-6 树形图,拆掉3-4这条边,交叉的访问这两个集合中的点,最优的顶点访问序列就是:3->6->2->5->1->4,一共经过17条边;
case2:存在一个顶点G,移除这个顶点以及与该点相连的边,图分成K个部分,每个部分的顶点数目Ti<=N/2,(i=1,...K)。那么,我们把G点作为访问的第一个点,再从这K个连通部分中,找到一个点v作为最后一个访问的顶点,要求该顶点v需与G直接相连。这样,就可以构造一个序列,使得属于同一个连通集里的两个顶点不会相邻。
#include <iostream> #include<cstdio> #include<vector> #include<cstring> #include<algorithm> #include<set> #include<queue> #include<map> #include<cmath> using namespace std; #define LL long long #define rep(i,a,n) for(int i=a;i<n;++i) #define per(i,a,n) for(int i=n-1;i>=a;--i) #define mem(a,t) memset(a,t,sizeof(a)) #define mp make_pair #define pb push_back #define fi first #define se second #define all(v) v.begin(),v.end() #define sz(v) ((int)sizeof(v)) const int inf=1e9; const int N=1e5+5; int n,splen=0,spv; LL ans=0; vector<pair<int,int> >g ; int c ; void dfs(int u,int pre,int len){ c[u]=1; int v,w,child=0; for(int i=0;i<g[u].size();++i){ v=g[u][i].fi; if(v==pre) continue; dfs(v,u,g[u][i].se); c[u]+=c[v]; child=max(child,c[v]); } child=max(child,n-c[u]); if(c[u]*2==n){ //case1 splen=len; } if(child<=n/2){ //case2 spv=u; //特殊点G, } ans+=2ll*len*min(c[u],n-c[u]); } int main(){ ios_base::sync_with_stdio(false); cin>>n; int u,v,w; rep(i,0,n-1){ cin>>u>>v>>w; g[u].pb(mp(v,w)); g[v].pb(mp(u,w)); } dfs(1,0,0); if(splen){ //case1 cout<<ans-splen<<endl; } else{ //case2 int mi=1e9; for(int i=0;i<g[spv].size();++i){ //找到和特殊点相邻的最小边e mi=min(mi,g[spv][i].se); } cout<<ans-mi<<endl; } return 0; }
相关文章推荐
- 【GCD】AtCoder Grand Contest 018 A - Getting Difference
- 【贪心】AtCoder Grand Contest 018 B - Sports Festival
- 【AtCoder】 Grand Contest 018 C - Coins
- 【贪心】【堆】AtCoder Grand Contest 018 C - Coins
- AtCoder Grand Contest 018 D - Tree and Hamilton Path 树的重心
- [AtCoder Grand Contest 018] D: Tree and Hamilton Path (agc018D)
- (技巧)AtCoder Grand Contest 018 C : Coins
- (贪心)AtCoder Grand Contest 018 B : Sports Festival
- AtCoder Grand Contest 018 E - Sightseeing Plan
- AtCoder Grand Contest 018A: Getting Difference 题解
- Atcoder Grand Contest 018 D Tree and Hamilton Path
- AtCoder Grand Contest 018B: Sports Festival 题解
- AtCoder Grand Contest 018 E Sightseeing Plan
- AtCoder Grand Contest 018 F - Two Trees 欧拉回路+构造
- AtCoder Grand Contest 018
- AtCoder Grand Contest 018 A - Getting Difference
- AtCoder Grand Contest 018 E - Sightseeing Plan
- AtCoder Grand Contest 018 --------- Getting Difference
- (组合计数)AtCoder Grand Contest 018 E - Sightseeing Plan
- AtCoder Grand Contest 018 A