题目大意
CJY很喜欢吃奶酪,于是YJC弄到了一些奶酪,现在YJC决定和CJY分享奶酪。
YJC弄到了n-1块奶酪,于是他把奶酪挂在了一棵n个结点的树上,每根树枝上挂一块奶酪,每块奶酪都有重量。
YJC和CJY决定这样分奶酪:首先砍掉一根树枝,把树分成两部分,每人取一部分,然后各自在自己取的那部分树上选择一条路径并取走路径上的奶酪,然后把剩下的奶酪拿去喂老鼠。
两人都想让自己取走总重量尽量大的奶酪,但他们不知道砍掉哪一根树枝最好。所以他们想让你计算,对于每一根树枝,砍掉之后每个人取走的奶酪的总重量的最大值。
解题思路
树形动态规划,枚举删哪一条边,维护往下三条链,往上一条链,子树直径,儿子子树两条直径,各种if即可。
code
#include<set>
#include
#include
#include
#include
#define LD double
#define LL long long
#define ULL unsigned long long
#define min(a,b) ((ab)?a:b)
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
using namespace std;
int const mn=4*1e6+9,mm=8*1e6+9,inf=1e9;LL mo=2333333333333333;
int n,gra,tag,ansp,begin[mn],to[mm],len[mm],num[mm],next[mm];
LL anss,f[mn][4][2],a[mn][3][2],g[mn],h[mn];
void insert(int u,int v ,int w,int p){
to[++gra]=v;
len[gra]=w;
num[gra]=p;
next[gra]=begin[u];
begin[u]=gra;
}
void add(int now,int pos,LL far){
fd(i,3,1){
if(f[now][i][0]>far)break;
f[now][i+1][0]=f[now][i][0];
f[now][i+1][1]=f[now][i][1];
f[now][i][0]=far;
f[now][i][1]=pos;
}
}
void dfs(int now,int pre){
fr(i,now)if(to[i]!=pre){
dfs(to[i],now);
add(now,to[i],f[to[i]][1][0]+len[i]);
h[now]=max(h[now],h[to[i]]);
}
h[now]=max(h[now],f[now][1][0]+f[now][2][0]);
}
LL get(int now,int tag){
fo(i,1,3)if(f[now][i][1]!=tag)return f[now][i][0];
}
LL get2(int now,int tag){
if(f[now][1][1]==tag)return f[now][2][0]+f[now][3][0];
else if(f[now][2][1]==tag)return f[now][1][0]+f[now][3][0];
else return f[now][1][0]+f[now][2][0];
}
void addh(int now,int pos,LL far){
fd(i,2,1){
if(a[now][i][0]>far)break;
a[now][i+1][0]=a[now][i][0];
a[now][i+1][1]=a[now][i][1];
a[now][i][0]=far;
a[now][i][1]=pos;
}
}
LL geth(int now,int tag){
fo(i,1,2)if(a[now][i][1]!=tag)return a[now][i][0];
}
void dfs2(int now,int pre,LL tmx){
fr(i,now)if(to[i]!=pre)
addh(now,to[i],h[to[i]]);
fr(i,now)if(to[i]!=pre){
LL tmp=get(now,to[i]);
g[to[i]]=max(tmp,g[now])+len[i];
tmp=h[to[i]];LL tmp2=get2(now,to[i]),tmp3=get(now,to[i])+g[now];
tmp2=max(tmp2,tmp3);tmp3=geth(now,to[i]);
tmp2=max(tmp2,tmp3);
tmp2=max(tmp2,tmx);
tmp3=max(tmp,tmp2);LL tmp4=min(tmp,tmp2);
anss=(anss+tmp3*23333+tmp4*2333+1ll*233*num[i]*num[i]+23*num[i]+2)%mo;
dfs2(to[i],now,tmp2);
}
}
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%d",&n);int u,v,w;
fo(i,1,n-1){
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w,i);insert(v,u,w,i);
}
dfs(1,0);
dfs2(1,0,0);
printf("%lld",anss);
return 0;
}