【模板】树的重心 洛谷P1364 医院设置
P1364 医院设置
题目描述
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为l。如上图中,
若医院建在1 处,则距离和=4+12+2*20+2*40=136;若医院建在3 处,则距离和=4*2+13+20+40=81……
输入输出格式
输入格式:
第一行一个整数n,表示树的结点数。(n≤100)
接下来的n行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。
输出格式:
一个整数,表示最小距离和。
输入输出样例
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0
81
【题解】
随便找个跟DFS一下,第一个子树权值 * 2>=总权值的点即为重心(为什么?我也不知道)
然后再DFS一下就好了
#include <bits/stdc++.h>
inline void read(int &x)
{
x = ;char ch = getchar();char c = ch;
while(ch > '' || ch < '')c = ch, ch = getchar();
while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
if(c == '-')x = -x;
} const int INF = 0x3f3f3f3f;
const int MAXN = + ; struct Edge
{
int u,v,next;
}edge[MAXN + ];
int head[MAXN],cnt,root,b[MAXN],n,sum,w[MAXN],ans; void insert(int a, int b){edge[++cnt] = Edge{a,b,head[a]};head[a] = cnt;} int dfs1(int u)
{
register int tmp = w[u];
for(register int pos = head[u];pos;pos = edge[pos].next)
{
int v = edge[pos].v;
if(!b[v])
{
b[v] = true;
tmp += dfs1(v);
if(tmp * >= sum && !root)
root = u;
if(root)
return ;
}
}
return tmp;
} void dfs2(int u, int step)
{
ans += w[u] * step;
for(register int pos = head[u];pos;pos = edge[pos].next)
{
int v = edge[pos].v;
if(!b[v])
{
b[v] = ;
dfs2(v, step + );
}
}
} int main()
{
read(n);
register int tmp1,tmp2,tmp3;
for(register int i = ;i <= n;++ i)
{
read(tmp1);read(tmp2);read(tmp3);
if(tmp2)
insert(i,tmp2),insert(tmp2,i);
if(tmp3)
insert(i,tmp3),insert(tmp3,i);
w[i] = tmp1;
sum += tmp1;
}
b[] = ;
dfs1();
memset(b, , sizeof(b));
b[root] = ;
dfs2(root, );
printf("%d", ans);
return ;
}
【模板】树的重心 洛谷P1364 医院设置的更多相关文章
- 洛谷 P1364 医院设置
题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为l.如上 ...
- 洛谷P1364 医院设置(Floyd)
题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为l.如上 ...
- 洛谷P1364 医院设置
LITTLESUN的第一道图论,撒花~~ 题目链接 这道题是Floyd的板子题 注意对于矩阵图的初始值赋值要全部赋值成最大值 十六进制的最大值表示方式是0x3f3f3f3f memset(G,0x3f ...
- P1364 医院设置 (补锅,memset初始化较大值不可用0x7fffffff )
P1364 医院设置 题解 弗洛伊德水过 注意初始化一个大数 0x3f 可以,0x5f 好像也可以,但是0x7fffffff 我是真的炸了,初始化为-1 (后面补锅有详细解释) 代码 #include ...
- 【洛谷 P1364】医院设置(树的重心)
树的重心的定义: 树若以某点为根,使得该树最大子树的结点数最小,那么这个点则为该树的重心,一棵树可能有多个重心. 树的重心的性质: 1.树上所有的点到树的重心的距离之和是最短的,如果有多个重心,那么总 ...
- P1364 医院设置
题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为l.如上 ...
- 树状数组模板(pascal) 洛谷P3374 【模板】树状数组1
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...
- P1364 医院设置 洛谷
https://www.luogu.org/problem/show?pid=1364 题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结 ...
- AC日记——【模板】树链剖分 洛谷 P3384
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
随机推荐
- NoSQL 文档数据库
- python基础-递归
1.递归调用:在一个函数调用的过程中,直接或间接又调用了自身,就是递归调用 2.递归必备的两个阶段:1.递推 2.回溯 总结:#总结递归的使用: 1. 必须有一个明确的结束条件2. 每次进入更深一层 ...
- 用JSON将一个字典写入到文件,通过loads()将JSON字符串在转换为本来的类型
通过dumps将字典转换为JSON的字符串,存到磁盘里面
- Ionic 日期时间插件
1.插件安装 日期插件 时间插件 备注: 具体 查看 https://github.com/rajeshwarpatlolla/ionic-datepicker https://github.c ...
- java连接达梦数据库的简单代码
1. 引用DmJdbcDriver.jar包 2. 编写代码: String driver= "dm.jdbc.driver.DmDriver"; String url= &quo ...
- Linq之Sum用法新体会
1.简单应用,求数组的和,示例: , , , , , , , , , }; double numSum = numbers.Sum(); Console.WriteLine("The sum ...
- 在线模拟http-post请求
今天,要测试一个post请求的API,找了下,下面的网站可以直接利用起来,mark下 http://www.atool.org/httptest.php
- Windows 常用工具 & 开发工具 & Chrome插件 & Firefox 插件 & 办公软件
常用工具 1.FastStone 8.0 2.印象笔记 3.Chrome 4.Beyond Compare 5.Everything 6.有道词典 7.文本编辑软件 EditPlus UltraEdi ...
- join和os.path.join 的用法
Python中有join和os.path.join()两个函数,具体作用如下: join:连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串os.path.joi ...
- 一次.NET项目反编译的实战经验(WinForm)
最近由于业务需求,需要对一个老项目进行功能调整.但是项目的源代码已经找不到了.所以只能尝试对项目行进反编译. 一.反编译工具的选择 提到.NET的反编译,第一个想到的就是大名鼎鼎的Reflector. ...