# [Poj 3107] Godfather 链式前向星+树的重心
[Poj 3107] Godfather 链式前向星+树的重心
题意
http://poj.org/problem?id=3107
给定一棵树,找到所有重心,升序输出,n<=50000。
链式前向星存储图
链式前向星是前向星的升级版本,是一种特殊的边集数组,有n条边,数组开n*2,切记!切记!!(由于要正反两次存边,也就是一条边要存两次),空间利用率高,并且速度比使用vector快,本题使用vector就TLE了一次。。
建立如下结构体:
struct node{
int to,next,w;
}edge[maxe]
其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置(使用链式前向星存储遍历的时候是逆序遍历的,所有这里其实是前一条边的位置),edge[i].w表示第i条边的权值
inline void add(int u,int v,int w){
edge[cnt].w=w,edge[i].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
初始cnt=0,表示第几条边
其中head[u]表示以u为起点的第一条边的存储位置,实际上,由于head[u]的值会不断被覆盖,存储的实际上是最后一条边的位置,遍历的时候其实是逆序遍历的
head[]一般初始化为-1
遍历以u节点为起始位置的所有边,终止位置i=-1
for(int i=head[u];~i;i=edge[i].next)
更详细的解释参考这篇博客:https://blog.csdn.net/acdreamers/article/details/16902023
树的重心
树的重心也叫树的质心,删除这个节点后,所有子树中最大子树节点数最小,也就是删点之后生成的多颗树尽可能平衡。
性质
- 树中所有节点到某个点的距离之和,到重心的距离和是最小的。
- 两棵树通过一条边相连,新树的重心在原来两棵树的重心连线上。
- 一棵树添加或删除一个节点,树的重心最多只移动一条边的位置。
- 一棵树最多两个重心,且相邻
算法实现
只需一遍dfs,复杂度O(n),遍历过程中找到以每个节点为根的子树中最大的子树(节点数最多),在所有最大子树中取最小值。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxe=5e4+5;
int n;
int mNode,mBalacne=0x7f7f7f7f;
int scld[maxn];
struct node{
int to,next;
}edge[maxe*2];
int head[maxn],cnt=0;
inline void add(int x,int y){
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
}
int ans[maxn],id=0;
void dfs(int u,int pa){
int maxSubT=0;
scld[u]=1;
for(int i=head[u];~i;i=edge[i].next){
int cld=edge[i].to;
if(cld!=pa){
dfs(cld,u);
scld[u]+=(scld[cld]);
//找除从父亲节点出发的那颗子树外,剩下的最大子树的节点个数的最大值
maxSubT=max(maxSubT,scld[cld]);
}
}
//最后和从父亲节点出发的那颗子树比较,找到以当前节点为根的最大子树
//这里的子树都是不包括当前节点的
maxSubT=max(maxSubT,n-scld[u]);
// cout<<u<<":"<<scld[u]<<" "<<maxSubT<<" "<<mBalacne<<endl;
if(maxSubT<mBalacne){
id=0,ans[id++]=u;
mBalacne=maxSubT;
}
else if(maxSubT==mBalacne){
ans[id++]=u;
}
//cout<<id<<endl;
}
int main(){
memset(head,-1,4*maxn);
cin>>n;
int x,y;
for(int i=0;i<n-1;i++){
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(1,0);//随便取一个节点开始遍历
sort(ans,ans+id);
for(int i=0;i<id;i++){
if(i)putchar(' ');
printf("%d",ans[i]);
}
return 0;
}
/*
6
1 2
1 3
2 4
2 5
5 6
6
1 3
1 4
1 5
2 3
2 6
6
1 2
1 4
1 3
2 5
4 6
*/
# [Poj 3107] Godfather 链式前向星+树的重心的更多相关文章
- 链式前向星版DIjistra POJ 2387
链式前向星 在做图论题的时候,偶然碰到了一个数据量很大的题目,用vector的邻接表直接超时,上网查了一下发现这道题数据很大,vector可定会超的,不会指针链表的我找到了链式前向星这个好东西,接下来 ...
- POJ 3169 Layout(差分约束+链式前向星+SPFA)
描述 Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 ...
- POJ 1655 Balancing Act ( 树的重心板子题,链式前向星建图)
题意: 给你一个由n个节点n-1条边构成的一棵树,你需要输出树的重心是那个节点,以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的 题解: 树的重心定义:找到一个点,其所 ...
- 链式前向星+SPFA
今天听说vector不开o2是数组时间复杂度常数的1.5倍,瞬间吓傻.然后就问好的图表达方式,然后看到了链式前向星.于是就写了一段链式前向星+SPFA的,和普通的vector+SPFA的对拍了下,速度 ...
- 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板
一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...
- hdu2647 逆拓扑,链式前向星。
pid=2647">原文地址 题目分析 题意 老板发工资,可是要保证发的工资数满足每一个人的期望,比方A期望工资大于B,仅仅需比B多1元钱就可以.老板发的最低工资为888元.输出老板最 ...
- 图的存储结构:邻接矩阵(邻接表)&链式前向星
[概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组gr ...
- 【模板】链式前向星+spfa
洛谷传送门--分糖果 博客--链式前向星 团队中一道题,数据很大,只能用链式前向星存储,spfa求单源最短路. 可做模板. #include <cstdio> #include <q ...
- zzuli 2131 Can Win dinic+链式前向星(难点:抽象出网络模型+建边)
2131: Can Win Time Limit: 1 Sec Memory Limit: 128 MB Submit: 431 Solved: 50 SubmitStatusWeb Board ...
随机推荐
- Towers of Hanoi Strike Back (URAL 2029)
Problem The Tower of Hanoi puzzle was invented by French mathematician Édouard Lucas in the second h ...
- 如何使用PHP排序key为字母+数字的数组
你还在为如何使用PHP排序字母+数字的数组而烦恼吗? 今天有个小伙伴在群里问: 如何将一个key为字母+数字的数组按升序排序呢? 举个例子: $test = [ 'n1' => 22423, ' ...
- 第一次使用Open Live Writer写博客
写一下来试一试,感觉还是蛮有趣的.但是我并不知道写下来的文章是什么格式的,我刚才用VS Code打开看了一下好像都是二进制格式. 7.5正式入职,已经过去七天了.等培训结束就要去Base地了,新的生活 ...
- socketserver(多连接)
正如前面的socket模块部分看到的一样,写一个简单套接字服务器不是很难,如果想实现超出继承的应用,最好寻求一些帮助,socketserver模块是标准库中很多服务器框架的基础,这些服务器架构包括Ba ...
- Spring Cloud Eureka(二):Eureka 注册中心体验
1.Eureka 简述 本文主要从应用角度体验一下注册中心的搭建和使用,后文会由浅入深学习Spring Cloud Eureka 的各种原理和机制. Spring Cloud Eureka 是 Spr ...
- Linux版本内核及安装后的简单操作命令介绍
一.Linux的版本与内核 1.Linux发行版 Linux发行版= Linux内核+应用程序 Redhat,CentOS,Ubuntu,Suse,红旗,Mint,Fedora CentOS:社区版操 ...
- HDU 2176 取(m堆)石子游戏 —— (Nim博弈)
如果yes的话要输出所有情况,一开始觉得挺难,想了一下也没什么. 每堆的个数^一下,答案不是0就是先取者必胜,那么对必胜态显然至少存在一种可能性使得当前局势变成必败的.只要任意选取一堆,把这堆的数目变 ...
- java随机生成6位随机数 5位随机数 4位随机数
随机数,应用会相当广,验证数,订单号,流水号拼接. 下面是java随机数生成语句: 生成6位随机数(不会是5位或者7位,仅只有6位): System.+)*)); 同理,生成5位随机数: System ...
- redis的主从复制原理
1. 前言 和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis主从复制可以根据是否是全量分为全量同 ...
- Python list 遇到的问题
1.list“+” 运算 <list += > diff. <ndarray +=> list1 += list2是追加,而不是加法运算 list1 = [0,0,0] lis ...