[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

树的重心

树的重心也叫树的质心,删除这个节点后,所有子树中最大子树节点数最小,也就是删点之后生成的多颗树尽可能平衡。

性质

  1. 树中所有节点到某个点的距离之和,到重心的距离和是最小的。
  2. 两棵树通过一条边相连,新树的重心在原来两棵树的重心连线上。
  3. 一棵树添加或删除一个节点,树的重心最多只移动一条边的位置。
  4. 一棵树最多两个重心,且相邻

算法实现

只需一遍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 链式前向星+树的重心的更多相关文章

  1. 链式前向星版DIjistra POJ 2387

    链式前向星 在做图论题的时候,偶然碰到了一个数据量很大的题目,用vector的邻接表直接超时,上网查了一下发现这道题数据很大,vector可定会超的,不会指针链表的我找到了链式前向星这个好东西,接下来 ...

  2. POJ 3169 Layout(差分约束+链式前向星+SPFA)

    描述 Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 ...

  3. POJ 1655 Balancing Act ( 树的重心板子题,链式前向星建图)

    题意: 给你一个由n个节点n-1条边构成的一棵树,你需要输出树的重心是那个节点,以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的 题解: 树的重心定义:找到一个点,其所 ...

  4. 链式前向星+SPFA

    今天听说vector不开o2是数组时间复杂度常数的1.5倍,瞬间吓傻.然后就问好的图表达方式,然后看到了链式前向星.于是就写了一段链式前向星+SPFA的,和普通的vector+SPFA的对拍了下,速度 ...

  5. 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

    一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...

  6. hdu2647 逆拓扑,链式前向星。

    pid=2647">原文地址 题目分析 题意 老板发工资,可是要保证发的工资数满足每一个人的期望,比方A期望工资大于B,仅仅需比B多1元钱就可以.老板发的最低工资为888元.输出老板最 ...

  7. 图的存储结构:邻接矩阵(邻接表)&链式前向星

    [概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组gr ...

  8. 【模板】链式前向星+spfa

    洛谷传送门--分糖果 博客--链式前向星 团队中一道题,数据很大,只能用链式前向星存储,spfa求单源最短路. 可做模板. #include <cstdio> #include <q ...

  9. zzuli 2131 Can Win dinic+链式前向星(难点:抽象出网络模型+建边)

    2131: Can Win Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 431  Solved: 50 SubmitStatusWeb Board ...

随机推荐

  1. Mybatis源码学习之类型转换(四)

    简述 JDBC数据类型与Java语言中的数据类型并不是完全对应的,所以在PreparedStatement为SQL语句绑定参数时,需要从Java类型转换成JDBC类型,而从结果集中获取数据时,则需要从 ...

  2. matlab 计算灰度图像的一阶矩、二阶矩、三阶矩

    ​   一阶矩,定义了每个颜色分量的平均强度 ​  二阶矩,反映待测区域颜色方差,即不均匀性 ​  三阶矩,定义了颜色分量的偏斜度,即颜色的不对称性 close all;clear all;clc; ...

  3. HTML/HTML5 知识点思维导图

    1 - 浏览器 | 浏览器页面构成 2 - 浏览器 | 浏览器内核相关知识点 3 - W3C | 对WEB标准以及W3C的理解与认识? 4 - 标签 | Doctype相关知识点 5 - 标签 | m ...

  4. mysql 1045 - Access denied for user 'root'@'*.*.*.*' (using password YES)

    远程无法连接mysql 解决方法: 1.在服务器登录数据 mysql -uroot -hlocalhost -P3306 -p Enter password: Welcome to the MySQL ...

  5. 【洛谷1361】 小M的作物(最小割)

    传送门 洛谷 Solution 这是一个比较实用的套路,很多题目都有用,而且这个套路难以口胡出来. 考虑把每一个附加贡献重新建一个点,然后向必需的点连边,流量为val. 然后直接种植的从源点向这个点连 ...

  6. 子类中执行父类的方法(引出super()与mro列表)

    1. 我们先想一下在python中如果子类方法中想执行父类的方法,有什么方式?大概有三种: Parent.__init__(self, name) # 通过父类的名字,指定调用父类的方法 super( ...

  7. 使用策略模式减少if else

    首先要明确的说出策略模式会不可避免导致你的代码类变得很多,如果对应方法逻辑很复杂时可采用,如果逻辑不是很复杂就有点大材小用了. package com.zihexin.application.stra ...

  8. python Telnet通讯

    摘要: python中telnetlib模块的使用: http://blog.csdn.net/five3/article/details/8099997 python实现telnet: http:/ ...

  9. Netty使用(一)

    1.Netty介绍 Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架: 提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器 ...

  10. Tomcat安装应用部署及配置文件解读

    Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选. Tomcat和Nginx,APa ...