[dfs] Jzoj P1497 景点中心

Posted comfortable

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[dfs] Jzoj P1497 景点中心相关的知识,希望对你有一定的参考价值。

Description

话说宁波市的中小学生在镇海中学参加计算机程序设计比赛,比赛之余,他们在镇海中学的各个景点参观。镇海中学共有n个景点,每个景点均有若干学生正在参观。这n个景点以自然数1至n编号,每两个景点的编号均不同。每两个景点之间有且只有一条路径。选择哪个景点集中的学生,才能使所有学生走过的路径之和最小呢?
 

Input

输入文件center.in中有若干行:
第一行只有一个正整数n,表示景点数。
第二行有n个1至1000间的整数,这n个整数间互相以一个空格分隔。其中第i个整数表示第i个景点处的学生数。
第三行至第n+1行,每行有三个整数I,j,k,表示景点i和景点j之间有一条长尾k的路径直接连接。其中i<>j,1≤i≤n,1≤j≤n;1≤k≤1000。

Output

输出文件center.out中有二行;
第一行只有一个整数i,表示在第i个景点处集中时,所有学生走过的路径之和最短。
第二行也只有一个整数,表示所有学生走过的路径之和的最小值。
 

Sample Input

4
3  2  4  1
1  2  5
3  1  6
2  4  4

Sample Output

1
43
 

Hint

技术分享图片




【数据限制】
所有的数据均随机生成,且满足:
30%的数据,1≤n≤200。
60%的数据,1≤n≤3000。
100%的数据,1≤n≤100000。

 

 

题解

  • 先可以定i为根,用dfs求出从i到根结点的价值和子树大小
  • 那么求完之后就可以求出所有点到i的距离
  • 设在A处集合时,所有人走的距离的和为B
  • 若C是A的儿子则所有人在C处集合的走的距离是C=B+(该边权值)*(总人数-2*size[C])

代码

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 struct edge {int to,from,v; }e[100010*2];
 5 int head[100010],n,cnt=1;
 6 long long size[100010],dis[100010],mn,ans;
 7 void insert(int x,int y,int v) { e[cnt].to=y; e[cnt].v=v; e[cnt].from=head[x]; head[x]=cnt++; }
 8 void dfs(int x,int fa)
 9 {
10     for (int i=head[x];i;i=e[i].from)
11         if (e[i].to!=fa)
12         {
13             dfs(e[i].to,x);
14             size[x]+=size[e[i].to];
15             dis[x]+=dis[e[i].to]+size[e[i].to]*e[i].v;
16         }
17 }
18 void dfs1(int x,int fa)
19 {
20     for (int i=head[x];i;i=e[i].from) 
21         if (e[i].to!=fa)
22         {
23             dis[e[i].to]=dis[x]+e[i].v*(size[1]-2*size[e[i].to]);  
24             dfs1(e[i].to,x);
25         }
26 }
27 int main()    
28 {
29     scanf("%d",&n);
30     for (int i=1;i<=n;i++) scanf("%lld",&size[i]);
31     for (int i=1;i<=n-1;i++)
32     {
33         int x,y,v;
34         scanf("%d%d%d",&x,&y,&v);
35         insert(x,y,v); insert(y,x,v);
36     }
37     dfs(1,0);
38     dfs1(1,0);
39     mn=10000000000000;
40     for (int i=1;i<=n;i++)
41         if (mn>dis[i]) 
42         {
43             mn=dis[i];
44             ans=i;
45         }
46     printf("%lld
%lld",ans,mn);
47     return 0;
48 }

 

以上是关于[dfs] Jzoj P1497 景点中心的主要内容,如果未能解决你的问题,请参考以下文章

[DFS]JZOJ 5916 flow

JZOJ622720190621ichi

[DFS]JZOJ 2941 贿赂

[状压DP][DFS]JZOJ 2679 跨时代

[dfs][树的直径] Jzoj P1737 删边

[并差集][lca][dfs] Jzoj P5798 树