P1395 会议(求树的重心)
Posted HWIM
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1395 会议(求树的重心)相关的知识,希望对你有一定的参考价值。
题目描述
有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1。现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地点设置在哪个村民的家中,并且这个距离总和最小是多少?若有多个节点都满足条件,则选择节点编号最小的那个点。
输入输出格式
输入格式:
第一行。一个数n,表示有n个村民。
接下来n-1行,每行两个数字a和b,表示村民a的家和村民b的家之间存在一条路径。
输出格式:
一行输出两个数字x和y
x表示村长将会在哪个村民家中举办会议
y表示距离之和的最小值
输入输出样例
输入样例#1:
4 1 2 2 3 3 4
输出样例#1:
2 4
说明
【数据范围】
70%数据n<=1000
100%数据n<=50000
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 const int MAXN=50005,INF=1e9; 6 struct Edge{ 7 int to,nxt; 8 }e[MAXN<<1]; 9 int n,cnt,ans,minn,size=INF; 10 int head[MAXN<<1],son[MAXN],dep[MAXN]; 11 bool vis[MAXN]; 12 13 void add(int u,int v) 14 { 15 ++cnt; 16 e[cnt].to = v; 17 e[cnt].nxt = head[u]; 18 head[u] = cnt; 19 } 20 21 void dfs(int cur) 22 { 23 vis[cur] = true; 24 son[cur] = 0; 25 int tmp = 0; 26 for (int i=head[cur]; i; i=e[i].nxt) 27 { 28 if (!vis[e[i].to]) 29 { 30 dfs(e[i].to); 31 son[cur] += son[e[i].to]+1; //加上自己 32 tmp = max(tmp,son[e[i].to]+1) ; 33 } 34 } 35 tmp = max(tmp,n-son[cur]-1); 36 if(size>tmp || (tmp==size&&ans>cur)) 37 { 38 ans = cur; 39 size = tmp; 40 } 41 } 42 void dfsdep(int x,int p,int d) 43 { 44 dep[x] = d; 45 for (int i=head[x]; i; i=e[i].nxt) 46 if(p!=e[i].to) 47 dfsdep(e[i].to,x,d+1); 48 } 49 int main() 50 { 51 scanf("%d",&n); 52 for (int x,y,i=1; i<n; ++i) 53 { 54 scanf("%d%d",&x,&y); 55 add(x,y); 56 add(y,x); 57 } 58 dfs(1); 59 dfsdep(ans,ans,0); 60 for (int i=1; i<=n; ++i) 61 minn += abs(dep[ans]-dep[i]); 62 printf("%d %d",ans,minn); 63 return 0; 64 }
以上是关于P1395 会议(求树的重心)的主要内容,如果未能解决你的问题,请参考以下文章