题目描述

国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。

我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。

在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。

现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。现在对于每个计划,我们想知道: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少

输入输出格式

输入格式:

第一行 n 表示点数。

接下来 n-1 行,每行两个数 a,b 表示 a 和 b 之间有一条边。点从 1 开始标号。

接下来一行 q 表示计划数。对每个计划有 2 行,第一行 k 表示这个计划选中了几个点。

第二行用空格隔开的 k 个互不相同的数表示选了哪 k 个点。

输出格式:

输出 q 行,每行三个数分别表示代价和,最小代价,最大代价。

输入输出样例

输入样例#1: 复制

10
2 1
3 2
4 1
5 2
6 4
7 5
8 6
9 7
10 9
5
2
5 4
2
10 4
2
5 2
2
6 1
2
6 1

输出样例#1: 复制

3 3 3
6 6 6
1 1 1
2 2 2 2 2 2

说明

对于第 1,2 个点: n<=10000

对于第 3,4,5 个点: n<=100000,交通网络构成一条链

对于第 6,7 个点: n<=100000

对于第 8,9,10 个点: n<=1000000

对于所有数据, q<=50000并且保证所有k之和<=2*n

看到k的和小于2*n,于是立刻想到建虚树

建出虚树后就dp

size[x]表示x的子树中关键点数

f[x]表示x子树中路径的贡献和

Min[x]表示x子树中离x距离最小的关键点的距离

Max[x]表示最大的距离

最大值和求和很简单

最大值总是要取到叶子节点,虚树中叶子节点总是关键点

答案取当前Max[x]+Max[v]+边权w,然后Max[x]=max(Max[x],Max[v]+d)

求和就考虑一条边的贡献

一条边的贡献次数显然是size[v]*(k-size[v])

所以f[x]+=f[v]+size[v]*(k-size[v])*w

求最小值的话,Min[x]初值正无穷

如果是关键点就直接取它的子树路径最小值,否则就是它的两个儿子的子树路径最小值相加

如果是关键点,更新答案后Min[x]要清0,作为接下来的端点

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 typedef long long lol;
  8 const int N=2000005;
  9 struct Node
 10 {
 11     int next,to;
 12 }edge[N],edge2[N];
 13 int inf=1e9;
 14 int dep[N],fa[N][21],dfn[N],cnt,bin[25],head[N],head2[N],num,ed[N];
 15 int size[N],vis[N],Max[N],Min[N],k,M,ans1,ans2,n,Lca,a[N],s[N],top;
 16 lol f[N];
 17 int gi()
 18 {
 19     char ch=getchar();
 20     int x=0;
 21     while (ch<'0'||ch>'9') ch=getchar();
 22     while (ch>='0'&&ch<='9')
 23     {
 24         x=x*10+ch-'0';
 25         ch=getchar();
 26     }
 27     return x;
 28 }
 29 bool cmp(int a,int b)
 30 {
 31     return dfn[a]<dfn[b];
 32 }
 33 void add(int u,int v)
 34 {
 35     num++;
 36     edge[num].next=head[u];
 37     head[u]=num;
 38     edge[num].to=v;
 39 }
 40 void add2(int u,int v)
 41 {
 42     if (u==v) return;
 43     num++;
 44     edge2[num].next=head2[u];
 45     head2[u]=num;
 46     edge2[num].to=v;
 47 }
 48 void dfs(int x,int pa)
 49 {int i;
 50     dep[x]=dep[pa]+1;
 51     dfn[x]=++cnt;
 52     for (i=1;bin[i]<=dep[x];i++)
 53     fa[x][i]=fa[fa[x][i-1]][i-1];
 54     for (i=head[x];i;i=edge[i].next)
 55     {
 56         int v=edge[i].to;
 57         if (v==pa) continue;
 58         fa[v][0]=x;
 59         dfs(v,x);
 60     }
 61     ed[x]=cnt;
 62 }
 63 int lca(int x,int y)
 64 {int as,i;
 65     if (dep[x]<dep[y]) swap(x,y);
 66     for (i=20;i>=0;i--)
 67     if (bin[i]<=dep[x]-dep[y])
 68     x=fa[x][i];
 69     if (x==y) return x;
 70     for (i=20;i>=0;i--)
 71     {
 72         if (fa[x][i]!=fa[y][i])
 73         {
 74             x=fa[x][i];y=fa[y][i];
 75         }
 76     }
 77     return fa[x][0];
 78 }
 79
 80 void dp(int x)
 81 {int i;
 82     size[x]=vis[x];
 83     Max[x]=0;Min[x]=inf;f[x]=0;
 84     for (i=head2[x];i;i=edge2[i].next)
 85     {
 86         int v=edge2[i].to,d=dep[v]-dep[x];
 87         dp(v);
 88         size[x]+=size[v];
 89         f[x]+=f[v]+1ll*size[v]*(k-size[v])*d;
 90         ans1=min(ans1,Min[x]+Min[v]+d);Min[x]=min(Min[x],Min[v]+d);
 91         ans2=max(ans2,Max[x]+Max[v]+d);Max[x]=max(Max[x],Max[v]+d);
 92     }
 93     if (vis[x]) ans1=min(ans1,Min[x]),ans2=max(ans2,Max[x]),Min[x]=0;
 94 }
 95 int main()
 96 {int i,u,v,j,q;
 97  cin>>n;
 98  bin[0]=1;
 99  for (i=1;i<=20;i++)
100  bin[i]=bin[i-1]*2;
101   for (i=1;i<=n-1;i++)
102    {
103       scanf("%d%d",&u,&v);
104       add(u,v);add(v,u);
105    }
106    dfs(1,0);
107    cin>>q;
108    while (q--)
109    {
110         k=gi();
111      M=k;
112         num=0;ans1=inf;ans2=0;
113         for (i=1;i<=k;i++)
114           a[i]=gi(),vis[a[i]]=1;
115         sort(a+1,a+k+1,cmp);
116         Lca=a[1];
117      for (i=2;i<=k;i++)
118        if (ed[a[i-1]]<dfn[a[i]])
119        a[++M]=lca(a[i-1],a[i]),Lca=lca(Lca,a[i]);
120        a[++M]=Lca;
121        sort(a+1,a+M+1,cmp);
122        M=unique(a+1,a+M+1)-a-1;
123        s[++top]=a[1];
124        for (i=2;i<=M;i++)
125        {
126            while (top&&ed[s[top]]<dfn[a[i]]) top--;
127            add2(s[top],a[i]);
128            s[++top]=a[i];
129        }
130        dp(Lca);
131        printf("%lld %d %d\n",f[Lca],ans1,ans2);
132         for (i=1;i<=M;i++)
133         vis[a[i]]=head2[a[i]]=0;
134    }
135 }

转载于:https://www.cnblogs.com/Y-E-T-I/p/8454972.html

[HEOI2014]大工程相关推荐

  1. BZOJ3611: [Heoi2014]大工程

    题解:虚树模板题 维护虚树 跑树dp即可 /**************************************************************Problem: 3611Use ...

  2. P4103 [HEOI2014]大工程

    P4103 [HEOI2014]大工程 题目描述 详见:P4103 [HEOI2014]大工程 Solution 显然是虚树的板子题啊(我也不造我为啥调了1h) 直接建虚树,DP. 两两路径和很好求, ...

  3. bzoj 3611: [Heoi2014]大工程(虚树+树形DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MB Submit: 1697  Solved: 718 [Submit][Stat ...

  4. [bzoj3611][Heoi2014]大工程

    [bzoj3611][Heoi2014]大工程 标签: 虚树 DP 题目链接 题解 发现\(\sum k与n\)是同阶的,很容易想到虚树. 那么难点就在dp统计上了. 对于和的话,dp[u]表示u子树 ...

  5. BZOJ 3611: [Heoi2014]大工程 [虚树 DP]

    传送门 题意: 多次询问,求最长链最短链链总长 煞笔$DP$记录$d,c,f,g$ $MD$该死拍了一下午没问题然后交上去就$T$ 然后发现树链剖分写成$size[v]+=size[u]$ 我想知道我 ...

  6. 2021年全球十大工程成就,中国有几个? | 科技袁人

    来源: 风云之声 视频链接: 西瓜视频: https://www.ixigua.com/7068180516549329415 本视频发布于2021年2月25日,观看量已达7.4万次 精彩呈现: 20 ...

  7. 《Engineering》评选2021年全球十大工程成就 | 中国工程院院刊

    来源:风云之声 "2021全球十大工程成就"发布 工程是现实的.直接的生产力,是人类改变世界的重要活动.古往今来,人类创造了众多令人惊叹的工程成就,持续带动着经济发展和社会的深刻变 ...

  8. 《Engineering》评选2021年全球十大工程成就

    来源:中国工程院院刊 "2021全球十大工程成就"发布 工程是现实的.直接的生产力,是人类改变世界的重要活动.古往今来,人类创造了众多令人惊叹的工程成就,持续带动着经济发展和社会的 ...

  9. 从复现人类智能到挑战AI大工程,智能计算正经历什么考验?

    来源:AI科技评论 作者:杏花 编辑:青暮 世界顶级机器学习专家Michael I.Jordan曾提出一个观点,他认为人工智能正逐步由原理性研究,走向人工智能大工程. Michael I.Jordan ...

  10. YouTube深度学习推荐系统的十大工程问题

    文 | 王喆 源 | https://zhuanlan.zhihu.com/p/52504407 这篇文章主要介绍了YouTube深度学习系统论文中的十个工程问题,为了方便进行问题定位,我们还是简单介 ...

最新文章

  1. Foundation 框架
  2. 再谈HTTP2性能提升之背后原理—HTTP2历史解剖
  3. .net之 datagrid
  4. povray[1] = 天空
  5. php基本功之_get(),_set()的用法
  6. 计算机控制z反变换公式,第三章 计算机控制系统的数学描述(修正Z变换).ppt
  7. [转载] numpy.reshape用法(自用)
  8. CentOS6.4 X86_64 kvm+PXE备忘
  9. 关于idea中运行maven项目报错显示找不到包或符号的问题——终极方案
  10. JAVA笔试题常见坑_java笔试常见的选择题(坑你没商量)
  11. 扫雷游戏网页版_借“买量”造爆款,梦幻西游网页版击穿H5游戏天花板
  12. 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。
  13. 如何使用 JavaScript 快速构建一个二维码生成器
  14. 基于OpenCv的人脸识别系统设计
  15. Odin Inspector 系列教程 --- 初识Odin序列化
  16. html表头固定原理,html Table 表头固定的实现
  17. winpe装linux系统下载,winpe 安装linux
  18. python3 题解(33 人民币金额大写)
  19. 微擎we7模块和模板安装方法
  20. GBK,UTF8是什么?

热门文章

  1. 网站发布后验证码不显示
  2. (转)Scala中协变(+)、逆变(-)、上界(:)、下界(:)简单介绍
  3. Linux程序包管理和yum用法
  4. BFS(双向) HDOJ 3085 Nightmare Ⅱ
  5. Spark源码系列(一)spark-submit提交作业过程
  6. Android之多种Bitmap效果
  7. Lambda 表达式入门,这篇够了!
  8. Myeclipse 2020.5 版本首发!支持 Java14
  9. Spring Cloud 2020 年路线图
  10. Java会走向晦暗吗?Kotlin会取而代之吗