求树的重心 DFS
树的重心
何谓重心
树的重心:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
树的重心可以通过简单的两次搜索求出,第一遍搜索求出每个结点的子结点数量son[u],第二遍搜索找出使max{son[u],n-son[u]-1}最小的结点。
实际上这两步操作可以在一次遍历中解决。对结点u的每一个儿子v,递归的处理v,求出son[v],然后判断是否是结点数最多的子树,处理完所有子结点后,判断u是否为重心。
以牛客的一道题:A病毒感染:https://www.nowcoder.com/acm/contest/214/A
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000") //c++
// #pragma GCC diagnostic error "-std=c++11"
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3) #include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime----------------------*/
int minn = inf;
int n,m;
const int maxn = ;
vector<int>mp[maxn];
int dp[maxn],d[maxn];
void dfs(int u,int fa){
dp[u] = ;
d[u] = ;
for(int i=; i<mp[u].size(); i++){
int v = mp[u][i];
if(v == fa)continue;
dfs(v, u);
dp[u] += dp[v];
d[u] = max(d[u], dp[v]);
} d[u] = max(d[u], n - dp[u]);
minn = min(minn, d[u]);
}
int main(){
scanf("%d%d", &n, &m);
for(int i=; i<=m; i++){
int u,v;
scanf("%d%d", &u, &v);
mp[u].pb(v); mp[v].pb(u);
}
dfs(, -);
// debug(minn);
for(int i=; i<=n; i++){
if(d[i] == minn){printf("%d ", i);}
}
printf("\n");
return ;
}
求树的重心 DFS的更多相关文章
- 求树的重心(POJ1655)
题意:给出一颗n(n<=2000)个结点的树,删除其中的一个结点,会形成一棵树,或者多棵树,定义删除任意一个结点的平衡度为最大的那棵树的结点个数,问删除哪个结点后,可以让平衡度最小,即求树的重心 ...
- POJ 1655 Balancing Act (求树的重心)
求树的重心,直接当模板吧.先看POJ题目就知道重心什么意思了... 重心:删除该节点后最大连通块的节点数目最小 #include<cstdio> #include<cstring&g ...
- POJ 1655 求树的重心
POJ 1655 [题目链接]POJ 1655 [题目类型]求树的重心 &题意: 定义平衡数为去掉一个点其最大子树的结点个数,求给定树的最小平衡数和对应要删的点.其实就是求树的重心,找到一个点 ...
- 洛谷P1395 会议(CODEVS.3029.设置位置)(求树的重心)
To 洛谷.1395 会议 To CODEVS.3029 设置位置 题目描述 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会 ...
- POJ 1655 Balancing Act(求树的重心--树形DP)
题意:求树的重心的编号以及重心删除后得到的最大子树的节点个数size,假设size同样就选取编号最小的. 思路:随便选一个点把无根图转化成有根图.dfs一遍就可以dp出答案 //1348K 125MS ...
- poj 1655 Balancing Act 求树的重心【树形dp】
poj 1655 Balancing Act 题意:求树的重心且编号数最小 一棵树的重心是指一个结点u,去掉它后剩下的子树结点数最少. (图片来源: PatrickZhou 感谢博主) 看上面的图就好 ...
- poj3107 求树的重心(&& poj1655 同样求树的重心)
题目链接:http://poj.org/problem?id=3107 求树的重心,所谓树的重心就是:在无根树转换为有根树的过程中,去掉根节点之后,剩下的树的最大结点最小,该点即为重心. 剩下的数的 ...
- 求树的重心 poj 1655
题目链接:https://vjudge.net/problem/POJ-1655 这个就是找树的重心,树的重心就是树里面找一个点,使得以这个点为树根的所有的子树中最大的子树节点数最小.题目应该讲的比较 ...
- poj3107 Godfather 求树的重心
Description Last years Chicago was full of gangster fights and strange murders. The chief of the pol ...
随机推荐
- 2019年一半已过,这些大前端技术你都GET了吗?- 上篇
一晃眼2019年已过大半,年初信誓旦旦要学习新技能的小伙伴们立的flag都完成的怎样了?2019年对于大前端技术领域而言变化不算太大,目前三大技术框架日趋成熟,短期内不大可能出现颠覆性的前端框架(内心 ...
- http://regex.alf.nu/ 非标准答案
Plain strings (207) foo Anchors (206) ...
- python log 设置
# -*- coding: utf-8 -*- import loggingfrom logging.handlers import TimedRotatingFileHandler # 按时间处理 ...
- java支付宝app支付-代码实现
1.我们需要在支付宝商户平台配置好,取到四个参数如下(这是支付宝官方配置地址):https://www.cnblogs.com/fuzongle/p/10217144.html 合作身份者ID:123 ...
- 基于 kubeadm 部署单控制平面的 k8s 集群
单控制平面不符合 HA 要求,但用于开发/测试环境不会有任何问题,如果资源足够的话(10台以上服务器,3台用于APIserver.3台用于 etcd 存储.至少3台用于工作节点.1台作为负载均衡),可 ...
- (十三)c#Winform自定义控件-导航菜单
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- EMCAscript6随心所记
es6的支持情况http://kangax.github.io/compat-table/es6/ 1.let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变 ...
- File Compression and Archiving in linux (linux 中文件的归档)
1. Compressing Files at the Shell Prompt Red Hat Enterprise Linux provides the bzip2, gzip, and zip ...
- Debian下Hadoop 3.12 集群搭建
Debian系统配置 我这里在Vmware里面虚拟4个Debian系统,一个master,三个solver.hostname分别是master.solver1.solver2.solver3.对了,下 ...
- Mysql主从复制原理及搭建
## Mysql主从复制原理 主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中.对于多级复制,数据库服务器即可充当主机,也可充当从 ...