首页 > 其他分享 >[AtCoder Grand Contest 018] D: Tree and Hamilton Path (agc018D)

[AtCoder Grand Contest 018] D: Tree and Hamilton Path (agc018D)

时间:2022-12-29 14:33:35浏览次数:61  
标签:pr AtCoder fs sz int mi Contest Tree include


原题链接
​​​https://agc018.contest.atcoder.jp/tasks/agc018_d​

Description

给出一棵N个点带边权的树

现在有一个N个点的完全图,一条边x,y的长度是这两点的在树上最短路长度

求这个完全图的最长汉密尔顿路径(即从任意点开始将每个点访问且仅访问一次的路径)长度

N<=100000
边权<=1e8

Solution

如果想按顺序DP那就很麻烦了

考虑树上每条边对答案的贡献

我们希望答案尽量大,那就是树上的边尽可能被完全利用
即最好是这条边两侧一边一个一边一个

那么答案很显然就是每条边边权*两侧点数的最小值*2

如何构造这么一种方案?

绕着重心跑
每次访问重心的和上次不同的子树就行了

注意这样重心要么是第一个访问的,要么是最后一个访问的

那么与重心相连的某条边只会算一次

如果只有一个重心那么减掉最小那个就行了

有两个重心的话就减掉两个重心相连那条边

Code

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 100005
#define LL long long
using namespace std;
int fs[N],nt[2*N],dt[2*N],n,m,sz[N],mw,mi,m2;
LL pr[2*N],ans;
void link(int x,int y,int z)
{
nt[++m]=fs[x];
dt[fs[x]=m]=y;
pr[m]=z;
}
void dfs(int k,int fa)
{
sz[k]=1;
int mx=0;
for(int i=fs[k];i;i=nt[i])
{
int p=dt[i];
if(p!=fa)
{
dfs(p,k);
sz[k]+=sz[p];
mx=max(mx,sz[p]);
ans+=(LL)min(sz[p],n-sz[p])*pr[i]*(LL)2;
}
}
if(max(mx,n-sz[k])==mi) m2=k;
if(max(mx,n-sz[k])<mi) mi=max(mx,n-sz[k]),mw=k,m2=0;
}
int main()
{
cin>>n;
mi=n;
fo(i,1,n-1)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
link(x,y,z),link(y,x,z);
}
dfs(1,0);
if(m2==0)
{
mi=1802201963;
for(int i=fs[mw];i;i=nt[i]) mi=min(mi,(int)pr[i]);
ans-=mi;
}
else
{
for(int i=fs[mw];i;i=nt[i])
{
if(dt[i]==m2)
{
ans-=pr[i];
break;
}
}
}
printf("%lld\n",ans);
}


标签:pr,AtCoder,fs,sz,int,mi,Contest,Tree,include
From: https://blog.51cto.com/u_15925597/5977148

相关文章

  • [AtCoder Grand Contest 071] E: Jigsaw (agc071E)
    原题链接​​​https://agc017.contest.atcoder.jp/tasks/agc017_e​​Description给出N块拼图每块拼图宽度为3,高度为相同的H拼图由3个宽度为1的部分拼接而成,第一部分......
  • git解决error: The following untracked working tree files would be overwritten by
    git解决error:Thefollowinguntrackedworkingtreefileswouldbeoverwrittenbycheckout在IDEA中进行分支切换时,出现如此错误,导致无法正常切换:error:Thefollowing......
  • AtCoder-abc230_g GCD Permutation 容斥
    J-GCDPermutation传送门:J-GCDPermutation知识点:素数筛、容斥定理、gcd题意:长度为n的一个排列a中,求满足\(gcd(i,j)!=1且gcd(a_i,a_j)!=1\)的i,j对数。i,j可以......
  • 【学习笔记】Link Cut Tree学习笔记
    \(\text{LinkCutTree}\)学习笔记参考资料:LCT总结(概念篇)byFlashHu应用对象在不改变树形态的前提下,树上求和求最值问题可以用树链剖分,树上统计问题可以用树分治。而......
  • 将git仓库从submodule转换为subtree
    三个脚本AlexanderMikhailiancat.gitmodules|whilereadidoif[[$i==\[submodule*]];thenmpath=$(echo$i|cut-d\"-f2)readi;readi;m......
  • AtCoder Beginner Contest 239总结
    由于比赛延期了一个星期,今天才打,恰巧我记错了时间,本来是8:00,我记成9:00,然后·········幸运的是我还是把前四题做出来了(intwentyminutes),由于时间问题,我......
  • Atcoder Beginner Contest 244总结
    这次的Rating凉了………………这次出乎T3意料的考了交互题,虽然很简单,但卡了我好久……T4考了一个神奇的东西,我用骗分大法水了过去……一看排名发现有快3000人得了1000分......
  • Atcoder Beginner Contest 242
    由于我8点半才下课,我只好晚半个小时再打,这次还行,排名3042五道题,秒了前三道,第四道不会,第五道想出正解,结果一直不对,比完后看了一下大佬的代码恍然大悟,但是比赛早已结束...........
  • 将git仓库从submodule转换为subtree
    三个脚本AlexanderMikhailiancat.gitmodules|whilereadidoif[[$i==\[submodule*]];thenmpath=$(echo$i|cut-d\"-f2)readi;readi;......
  • SEERC2022 D Divisible by 4 Spanning Tree 题解
    题意给定\(n\)个点\(m\)条边的无向连通图,判断是否有存在生成树满足:度数为奇数的点个数为\(4\)的倍数。\(1\len\le200000,1\lem\le400000\)题解度数总和是\(2n......