SGU 134.Centroid(图心)
时间限制:0.25s
空间限制:4M
题意:
给出一个树(节点数<=16000),一个节点的重量定义为从树中去除这个点后,新得到的所有树中节点最多的树的节点数。树的中心定义为所有节点重量最小的那几个。
要求输出给定树的树的中心的重量,以及所有的树心的编号。
Solution:
首先,以任意节点为根,构造一颗具有父子节点关系的树。
使用递归即可,Fa[i]记录i的父亲节点编号。
sum[i],记录i节点以其所有儿子节点一共有多少个节点。
显然如果以1号节点为根 sum[1]=n;
再来考虑如何得到一个节点的重量。
对于根节点,它的重量是 所有 儿子节点sum[j]中的最大值。
对于根节点的儿子k呢?
它的重量是他的 所有儿子节点的sum[]和 (sum[1]-sum[k])的最大值。
那么对于k的儿子呢?
这时可以注意到计算k 的时候与根节点其他儿子已经没有关系了,需要的只是sum[i],
在计算k儿子时,把k当做根,这时sum[k]=n;
设p为k的儿子,
p的重量就是 它所有儿子的sum[]和 (sum[k]-sum[p])的最大值.
最后只要存下不同重量的节点有哪一些输出就可以了。
参考代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
#define INF 16666
using namespace std;
struct node {
int v, ne;
} edge[INF<<2];
queue<int> ql;
int head[INF], fa[INF], pd[INF];
int sum[INF], cnt, nCnt[INF];
vector<int> out[INF];
int n, m, ans = INF;
void added (int u, int v) {
edge[++cnt].v = v;
edge[cnt].ne = head[u];head[u] = cnt;
}
int Count (int x) {
pd[x] = sum[x] = 1;
for (int i = head[x]; i != 0; i = edge[i].ne) {
int j = edge[i].v;
if (!pd[j]) {
fa[j] = x;
sum[x] += Count (j);
}
}
return sum[x];
}
void make (int x) {
int k=0;
if (fa[x] != 0) k = sum[fa[x]] - sum[x];
for (int i = head[x]; i != 0; i = edge[i].ne) {
int j = edge[i].v;
if (j != fa[x]){
k = max (k, sum[j]);
if(fa[x]!=0) sum[x]=sum[fa[x]];
make(j);
}
}
if (ans >= k) {
ans = k;
out[k].push_back (x);
nCnt[k]++;
}
}
int main() {
int x, y, c;
scanf ("%d", &n);
for (int i = 1; i <= n - 1; i++) {
scanf ("%d %d", &x, &y);
added (x, y), added (y, x);
}
Count (1);
make (1);
printf ("%d %d\n", ans, nCnt[ans]);
sort (out[ans].begin(), out[ans].end() );
for (int i = 0; i <= out[ans].size() - 1; i++)
printf ("%d ", out[ans][i]);
return 0;
}
SGU 134.Centroid(图心)的更多相关文章
- SGU 134.Centroid( 树形dp )
一道入门树dp, 求一棵树的重心...我是有多无聊去写这种题...傻X题写了也没啥卵用以后还是少写好.. ----------------------------------------------- ...
- SGU 134 Centroid
题意:给出一个树,每个点有一个value,value的意义是去掉这个点之后所有连通分量中点最多的那个连通分量的点数,这棵树的重心为所有点value的最小值,求重心,及重心都有谁. 解法:貌似是个树形d ...
- 树形DP求树的重心 --SGU 134
令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...
- Centroid - SGU 134(树的搜索)
题目大意:给你一个树,树每个点都有一个值, 这个点的的值就等于所有儿子里面点最多的那个儿子,值最小的就叫做重心,求出重心,还有所有等于重心的点,按照升序输出. 分析:就是一个简单的搜索树,求出来最大的 ...
- SGU Volume 1
SGU 解题报告(持续更新中...Ctrl+A可看题目类型): SGU101.Domino(多米诺骨牌)------------★★★type:图 SGU102.Coprimes(互质的数) SGU1 ...
- SGU 乱乱开
本解题报告 乱抄,乱写,随性随心,不喜多喷! SGU 142: 思路:一个string的字串不会超过2^20个,我们枚举出来就好了. 我出错点:数组RE #include<stdio.h> ...
- SGU 分类
http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...
- 快速切题 sgu134.Centroid 树形dp
134. Centroid time limit per test: 0.25 sec. memory limit per test: 4096 KB You are given an undirec ...
- SGU 乱搞日志
SGU 100 A+B :太神不会 SGU 101 Domino: 题目大意:有N张骨牌,两张骨牌有两面有0到6的数字,能相连当且仅当前后数字相同,问能否有将N张骨牌连接的方案?思路:裸的欧拉回路,注 ...
随机推荐
- MYSQL仅仅向某个字段进行插入
例子: mysql> show create table student \G . row *************************** Table: student Create T ...
- Y86处理器的各个阶段
0x00e:30f480000000 | irmovl $128,%esp 实现所有Y86指令所需要的计算分为6个基本阶段:取值.译码.执行.访存.写回和更新 ...
- .net开源工作流引擎ccflow
关于济南驰骋信息技术有限公司的.net开源工作流引擎 驰骋工作流引擎,工作流程管理系统:简称ccflow,驰骋一体化解决方案简称ccport. ccflow是济南驰骋信息技术有限公司向社会提供的一款1 ...
- java 内存泄露 学习
1.什么事内存泄露 内存泄露就是对象不用了,但是无法回收该对象占用的内存. 2.java不是有垃圾回收机制,咋还会发生内存泄露呢? java的垃圾回收机制就是把无用的对象(GC roots可达与否)用 ...
- css背景图片位置:background的position
position的两个参数:水平方向的位置,垂直方向的位置----------该位置是指背景图片相对于前景对象的 1.background:url(../image/header.jpg) no-re ...
- m版页面判断安卓与ios系统
安卓系统和ios系统,在做app里面嵌入m版时,有时候会发现,ios上面的那个电池状态栏不占位置,但是安卓的状态栏占位,所以需要区分系统样式单独处理一下! var sUserAgent=navigat ...
- div样式调整小结 转载
1.多个div使用会自动换行,应该使用float属性 left : 对象浮在左边 right : 对象浮在右边 例如: float: left 和 float: right 是两个div左右排 ...
- Mysql性能优化那些事
对于全栈而言,数据库技能不可或缺,关系型数据库或者nosql,内存型数据库或者偏磁盘存储的数据库,对象存储的数据库或者图数据库--林林总总,但是第一必备技能还应该是MySQL.从LAMP的 ...
- 开发期间的GWT设置---加快编译速度
随着项目功能的完善,GWT模块(Module)越来越多,当要以web模式编译给测试组使用时,编译的总时间越来越多,我的机器编译完8个模块,需要10分钟左右. 抽空研究了一下GWT的编译参数和GWT编译 ...
- mysql 锁 实验
CREATE TABLE `kk` ( `a` ) NOT NULL, `b` ) NOT NULL, `c` ) NOT NULL, PRIMARY KEY (`a`), UNIQUE KEY `b ...