题意:

$mhy$ 住在一棵有 $n$ 个点的树的 $1$ 号结点上,每个结点上都有一个妹子。

$mhy$ 从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装 $zhx$ 牌杀毒软件,第 $i$ 个妹子安装时间为 $Ci$。

树上的每条边 $mhy$ 能且仅能走两次,每次耗费 $1$ 单位时间。$mhy$ 送完所有电脑后会回自己家里然后开始装 $zhx$ 牌杀毒软件。

卸货和装电脑是不需要时间的。

求所有妹子和 $mhy$ 都装好 $zhx$ 牌杀毒软件的最短时间。

题解:由于每条边最多走两次,所以如果进入点 $x$,必须要遍历完 $x$ 的所有子节点才能出来,我们考虑树形dp.

令 $f[i]$ 表示进入点 $i$ ,安装完 $i$ 子树中所有电脑的最小时刻,$size[i]$ 表示 $i$ 点子树中节点数量.

那么,对于点 $i$ 来说,我们就是要安排一个遍历 $i$ 点所有儿子的顺序,使得:

$max(f[1]+1,2size[1]+f[2]+1,2size[1]+2size[2]+f[3]+1,.....\sum_{i=1}^{n-1}size[i]+f[n]+1)$ 的最大值最小.

但是,我们并不知道该如何安排遍历儿子的顺序,但是我们可以考虑只有两个儿子的情况,然后发现:

若有 $i,j$ 而 $f[i]-2size[i]<f[j]-2size[j]$,则 $j$ 在 $i$ 之前访问更优.

对儿子排完序后依次累加即可.

#include <bits/stdc++.h>
#define N 500004
#define LL long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
struct data
{
int f,size,id;
data(int f=0,int size=0,int id=0):f(f),size(size),id(id){}
};
bool cmp(data a,data b)
{
return a.f-2*a.size==b.f-2*b.size?a.f>b.f:a.f-2*a.size>b.f-2*b.size;
}
int n,edges;
vector<data>G[N];
int hd[N],to[N<<1],nex[N<<1],val[N],f[N],size[N];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs(int u,int ff)
{
size[u]=1;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff) continue;
dfs(v,u);
G[u].push_back(data(f[v]+1,size[v],v));
size[u]+=size[v];
}
sort(G[u].begin(),G[u].end(),cmp);
int cur=0;
if(u!=1) f[u]=val[u];
for(int i=0;i<G[u].size();++i)
{
f[u]=max(f[u],cur+G[u][i].f);
cur+=2*G[u][i].size;
}
}
int main()
{
// setIO("input");
int i,j;
n=rd();
for(i=1;i<=n;++i) val[i]=rd();
for(i=1;i<n;++i)
{
int u,v;
u=rd(),v=rd();
add(u,v), add(v,u);
}
dfs(1,0);
f[1]=max(f[1], size[1]*2-2+val[1]);
printf("%d\n",f[1]);
return 0;
}

  

最新文章

  1. 利用SimpleExpandableListAdapter为ExpandableListActivity提供数据
  2. WSDL项目---添加头信息和附件
  3. AngularJS之Provider, Value, Constant, Service, Factory, Decorator的区别与详解
  4. 使用dynamic类型改进反射
  5. 专访Linux嵌入式开发韦东山操作系统图书作者--转
  6. win7上帝模式
  7. SEO 网站URL优化
  8. Jedis超时时间设置梳理
  9. c语言的lua库编写
  10. 文件同步服务器,iis 集群 ,代码同步(一)
  11. 浅谈js中的浅拷贝和深拷贝
  12. Python函数篇(7)-正则表达式
  13. JVM-触发Full GC的情况
  14. Spark技术内幕:Executor分配详解
  15. Dynamics CRM2013 picklist下拉项行数控制
  16. python之路-----前端之html协议一
  17. android--------动画之进度条
  18. Spark性能优化:数据倾斜调优
  19. Html5 拖拽行为和AngularJs的结合
  20. Python - TypeError: unicode argument expected, got &#39;str&#39;

热门文章

  1. 【Linux】一步一步学Linux——初识Linux命令解析器(10)
  2. Mitsubishi (三菱) Fanuc(发那科),CNC,网口数据采集,NC程序下发(其它品牌CNC,哈斯 马扎克 兄弟等,正在开发中)
  3. 为什么我们要用Spring Boot?
  4. [SOJ #538]好数 [CC]FAVNUM(2019-8-6考试)
  5. Luogu4705 玩游戏 分治FFT
  6. redis连接相关命令
  7. python3基础之“函数(2)”
  8. React Native 开发豆瓣评分(二)路由配置
  9. robot framework笔记(三):扩展SeleniumLibrary库 (自定义关键字)
  10. ubuntu安裝postman遇到問題