首页 技术 正文
技术 2022年11月21日
0 收藏 963 点赞 3,610 浏览 2431 个字

前言

本人在此题有一种不是题解的方法,但无法证明也找不到反例。

如果各位大神有反例或证明请发至

邮箱:qq1350742779@163.com

Description

Alice和Bob有一棵树(无根、无向),在第i个点上有ai个巧克力。首先,两人个选择一个起点(不同的),获得点上的巧克力;接着两人轮流操作(Alice先),操作的定义是:在树上找一个两人都没选过的点并获得点上的巧克力,并且这个点要与自己上一次选的点相邻。当有一人无法操作 时,另一个人可以继续操作,直到不能操作为止。因为Alice和Bob是好朋友,所以他们希望两人得到的巧克力总和尽量大,请输出最大总和。

Input

第一行一个整数n,表示树的点数

第二行有n个整数,表示每个点上的巧克力数量ai

接下来n-1行,每行两个整数u、v,表示u和v之间有一条边。

Output

输出一个整数,表示两人能获得得巧克力的最大总和。

Sample Input

9

1 2 3 4 5 6 7 8 9

1 2

1 3

1 4

1 5

1 6

1 7

1 8

1 9

Sample Output

25

Data Constraint

对于20%的数据,n<=15

对于40%的数据,n<=100

对于60%的数据,n<=5000

对于100%的数据,n<=200000,0<=ai<=1000000000(1e9)

我的方法

首先随便找一条直径,然后删掉这些的,在剩下的森林中再找一条最长的链,输出总和。

或者,

首先随便找一条直径,枚举这条直径上的两个点,从这两个点出发分别找到最长链,答案就是这条直径加上从枚举的两个点找到的最长链再减去枚举的两个点在直径之间的路径。

将两者去最大值输出。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=1000000007;
const long long N=200005;
using namespace std;
long long n,v[N],next[N*2],last[N*2],to[N*2],tot,ans,mxp,pos,bz[N],s,t,st[N],ts[N],num,ans1,ans2,ans3,ans4,ans5,vv;
long long bj(long long x,long long y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
long long dg(long long x,long long fa,long long sum)
{
if(sum>ans) ans=sum,mxp=x;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=fa && bz[j]==0) dg(j,x,sum+v[j]);
}
}
long long dg1(long long x,long long fa)
{
if(mxp==x && !bz[x]) bz[x]=vv;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=fa && bz[j]==0)
{
dg1(j,x);
if(bz[j])
{
bz[x]=vv;
break;
}
}
}
}
long long dg2(long long x,long long fa,long long sum)
{
ans=0;
dg(x,fa,0);
st[++tot]=ans+sum;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=fa && bz[j]==vv)
{
dg2(j,x,sum+v[j]);
}
}
}
long long dg3(long long x,long long fa,long long sum)
{
ans=0;
dg(x,fa,0);
ts[tot--]=ans+sum;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=fa && bz[j]==vv)
{
dg3(j,x,sum+v[j]);
}
}
}
int main()
{
scanf("%lld",&n);
for(long long i=1;i<=n;i++) scanf("%lld",&v[i]);
for(long long i=1;i<=n-1;i++)
{
long long x,y;
scanf("%lld%lld",&x,&y);
bj(x,y);
bj(y,x);
}
vv++;
dg(1,0,v[1]);
pos=mxp;
ans=0;
dg(pos,0,v[pos]);
dg1(pos,0);
s=mxp;
ans=0;
dg(pos,0,v[pos]);
dg1(pos,0);
t=mxp;
tot=0;
dg2(s,0,v[s]);
num=tot;
dg3(t,0,v[t]);
ans1=st[num];
for(int i=1;i<=num;i++) st[i]=max(st[i],st[i-1]);
for(int i=num;i>=1;i--) ts[i]=max(ts[i],ts[i+1]);
ans=0;
for(int i=1;i<=num-1;i++) ans=max(ans,st[i]+ts[i+1]);
ans5=ans;
for(int k=1;k<=n;k++)
if(!bz[k])
{
vv++;
tot=0;
num=0;
ans=0;
dg(k,0,v[k]);
pos=mxp;
ans=0;
dg(pos,0,v[pos]);
dg1(pos,0);
s=mxp;
ans=0;
dg(pos,0,v[pos]);
dg1(pos,0);
t=mxp;
tot=0;
dg2(s,0,v[s]);
num=tot;
ans3=max(ans3,st[num]);
}
printf("%lld",max(ans5,ans1+ans3));
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,918
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,444
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,255
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,069
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,701
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,741