# [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 ...
随机推荐
- 刚注册blog,先来刷个存在
我想以后能够走数字ic设计的道路,努力复习考研,努力提升专业素养,2017加油!青春加油!
- python 编写排列组合
python在编写排列组合是会用到 itertools 模块 排列 import itertools mylist = list(itertools.permutations([)) # 全排列 p ...
- Django基础之response对象
与由DJango自动创建的HttpRequest对象相比, HttpResponse对象是我们的职责范围了. 我们写的每个视图都需要实例化, 填充和返回一个HttpResponse. HttpResp ...
- Spring学习随笔(2):Eclipse下Spring环境配置+入门项目
1 准备工作 (按需下载) Eclipse 下载:http://www.eclipse.org/downloads/eclipse-packages/ : Spring 下载:http://repo. ...
- gitolite 代码访问控制
gitolite可用于代码访问控制,这里汇总一下git相关的内容. git quick start:创建git仓库 TortoiseGit:可视化git操作 egit eclipse插件:新版的IDE ...
- Netfilter 之 iptable_nat
初始化 iptable_nat_table_init函数通过调用ipt_register_table完成NAT表注册和钩子函数注册的功能:该流程与iptable_filter的函数调用的函数一致,此处 ...
- Matlab - Matlab 2016a 安装破解教程
https://blog.csdn.net/u012313335/article/details/73733651/ Matlab 2016a 安装包及破解教程百度云分享链接: 链接:https:// ...
- VC++实现标准型计算器步骤及源码
VC++实现标准型计算器步骤及源码 2013年06月19日 09:48:47 无敌的成长日记 阅读数:4686 最近一段时间一直在做这个东西,刚刚拿到题目的时候认为这是一个简单的程序,可是 ...
- PHP学习之PHP代码的优化
if代码块的优化 if(1===$orderState){ $status='success'; }else{ $status='error'; } return $status; 简 ...
- 后缀数组--summer-work之我连模板题都做不起
这章要比上章的AC自动机要难理解. 这里首先要理解基数排序:基数排序与桶排序,计数排序[详解] 下面通过这个积累信心:五分钟搞懂后缀数组!后缀数组解析以及应用(附详解代码) 下面认真研读下这篇: [转 ...