题目传送门:https://agc018.contest.atcoder.jp/tasks/agc018_d

题目大意:

给定一棵\(N\)个点的带权树,求最长哈密顿路径(不重不漏经过每个点一次,两点之间转移可以看做瞬移,对答案贡献为两点之间的距离)


这道题直接计算不好算,我们考虑每条边的贡献,基于一种贪心的思想,我们发现只要围着树的重心跑,就可以使每条边得到充分利用

考虑边i的贡献,我们假定边i割掉后分成两个大小为x,y的联通块,那么贡献则为\(2*v[i]*min(x,y)\)

因为我们走的不是回路,因此有一条边不会被算两次。如果树的重心只有一个,那么必然减去与重心相连的边权最小的边;如果树的重心有两个,减去两重心相连的边即可

  1. /*program from Wolfycz*/
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<algorithm>
  7. #define inf 0x7f7f7f7f
  8. using namespace std;
  9. typedef long long ll;
  10. typedef unsigned int ui;
  11. typedef unsigned long long ull;
  12. inline char gc(){
  13. static char buf[1000000],*p1=buf,*p2=buf;
  14. return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
  15. }
  16. inline int frd(){
  17. int x=0,f=1;char ch=gc();
  18. for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
  19. for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
  20. return x*f;
  21. }
  22. inline int read(){
  23. int x=0,f=1;char ch=getchar();
  24. for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
  25. for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
  26. return x*f;
  27. }
  28. inline void print(int x){
  29. if (x<0) putchar('-'),x=-x;
  30. if (x>9) print(x/10);
  31. putchar(x%10+'0');
  32. }
  33. const int N=2e5;
  34. int pre[(N<<1)+10],now[N+10],child[(N<<1)+10],val[(N<<1)+10];
  35. int size[N+10],Msize[N+10];
  36. int n,tot,rize,root;
  37. ll Ans;
  38. void join(int x,int y,int z){pre[++tot]=now[x],now[x]=tot,child[tot]=y,val[tot]=z;}
  39. void insert(int x,int y,int z){join(x,y,z),join(y,x,z);}
  40. void dfs(int x,int fa,int v){
  41. int Max=0; size[x]=1;
  42. for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){
  43. if (son==fa) continue;
  44. dfs(son,x,val[p]),size[x]+=size[son];
  45. Max=max(Max,size[son]);
  46. }
  47. Ans+=1ll*min(size[x],n-size[x])*v*2;
  48. Max=max(Max,n-size[x]);
  49. Msize[x]=Max;
  50. if (Max<rize){
  51. rize=Max;
  52. root=x;
  53. }
  54. }
  55. int main(){
  56. n=read(),rize=inf;
  57. for (int i=1;i<n;i++){
  58. int x=read(),y=read(),z=read();
  59. insert(x,y,z);
  60. }
  61. dfs(1,0,0);
  62. int tmp=inf;
  63. for (int p=now[root],son=child[p];p;p=pre[p],son=child[p]){
  64. tmp=min(tmp,val[p]);
  65. if (Msize[root]==Msize[son]){
  66. Ans-=val[p];
  67. printf("%lld\n",Ans);
  68. return 0;
  69. }
  70. }
  71. printf("%lld\n",Ans-tmp);
  72. return 0;
  73. }

AtCoder Grand Contest 018 D - Tree and Hamilton Path的更多相关文章

  1. AtCoder Grand Contest 010 F - Tree Game

    题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_f 题目大意: 给定一棵树,每个节点上有\(a_i\)个石子,某个节点上有一个棋子,两人轮流操 ...

  2. AtCoder Grand Contest 005 C - Tree Restoring

    题目传送门:https://agc005.contest.atcoder.jp/tasks/agc005_c 题目大意: 给定一个长度为\(N\)的整数序列\(A_i\),问能否构造一个\(N\)个节 ...

  3. AtCoder Grand Contest 018 A

    A - Getting Difference Time limit時間制限 : 2sec / Memory limitメモリ制限 : 256MB 配点 : 300 点 問題文 箱に N 個のボールが入 ...

  4. AtCoder Grand Contest 018 E Sightseeing Plan

    题意: 给定三个矩形,选定三个点,答案加上第一个点出发经过第二个点在第三个点结束的方案数,只能往右或往下走. 折腾了我半个多下午的题. 设三个矩形为$A,B,C$一个思路是枚举$B$的那个点$s(x, ...

  5. 【贪心】【堆】AtCoder Grand Contest 018 C - Coins

    只有两维的时候,我们显然要按照Ai-Bi排序,然后贪心选取. 现在,也将人按照Ai-Bi从小到大排序,一定存在一个整数K,左侧的K个人中,一定有Y个人取银币,K-Y个人取铜币: 右侧的X+Y+Z-K个 ...

  6. 【贪心】AtCoder Grand Contest 018 B - Sports Festival

    假设我们一开始选取所有的运动项目,然后每一轮将当前选择人数最多的运动项目从我们当前的项目集合中删除,尝试更新答案.容易发现只有这样答案才可能变优,如果不动当前选取人数最多的项目,答案就不可能变优. 我 ...

  7. 【GCD】AtCoder Grand Contest 018 A - Getting Difference

    从大到小排序,相邻两项作差,求gcd,如果K是gcd的倍数并且K<=max{a(i)},必然有解,否则无解. 可以自己手画画证明. #include<cstdio> #include ...

  8. AtCoder Grand Contest 018 A - Getting Difference

    A - Getting Difference Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement ...

  9. AtCoder Grand Contest 018题解

    传送门 \(A\) 根据裴蜀定理显然要\(k|\gcd(a_1,...,a_n)\),顺便注意不能造出大于\(\max(a_1,...,a_n)\)的数 int n,g,k,x,mx; int mai ...

随机推荐

  1. 深入理解JVM:HotSpot虚拟机对象探秘

    对象的创建 java是一门面向对象的语言.在Java程序执行过程中无时无刻有Java对象被创建出来.在语言层面上,创建对象(克隆.反序列化)一般是一个newkeyword而已,而在虚拟机中,对象的创建 ...

  2. 【读书笔记】iOS-GCD-用法

    代码: -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { dispatch_async(dispatch_get_gl ...

  3. c++vector简单实现

    const int DEFAULT_CAP = 3; template <typename T> class vector { // int capacity; T* _data; int ...

  4. apache benchmark

    1 ab是什么 是一个web高并发测试工具,可以发送get.put.post请求. 2 ab -n和-c共存 -c是concurrency的缩写,即同一时间发送多个请求. -n是指本次总共发送多少个请 ...

  5. Phoenix put the sql back in NoSql

    Overview | Apache Phoenix http://phoenix.apache.org/index.html Apache Phoenix enables OLTP and opera ...

  6. opencv IplImage各参数详细介绍以及如何从一个JPEG图像数据指针转换得到IplImage

    这篇文章里介绍得最清楚了.http://blog.chinaunix.net/uid-22682903-id-1771421.html 关于颜色空间  RGB颜色空间已经非常熟悉了.HSV颜色空间需要 ...

  7. POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)

    Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14021   Accepted: 5484   Specia ...

  8. zoj 3204 Connect them(最小生成树)

    题意:裸最小生成树,主要是要按照字典序. 思路:模板 prim: #include<iostream> #include<stdio.h> #include<string ...

  9. Opencv中视频播放与进度控制

    视频画面本质上是由一帧一帧的连续图像组成的,播放视频其实就是在播放窗口把一系列连续图像按一定的时间间隔一幅幅贴上去实现的. 人眼在连续图像的刷新最少达到每秒24帧的时候,就分辨不出来图像间的闪动了,使 ...

  10. AtCoder3857:Median Sum (Bitset优化背包&&对称性求中位数)

    Median Sum You are given N integers A1, A2, ..., AN. Consider the sums of all non-empty subsequences ...