P1395 会议(树的重心)
Posted CCSU_Cola
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1395 会议(树的重心)相关的知识,希望对你有一定的参考价值。
有一个村庄居住着 n 个村民,有 n-1 条路径使得这 n 个村民的家联通,每条路径的长度都为 1。现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地点设置在哪个村民的家中,并且这个距离总和最小是多少?若有多个节点都满足条件,则选择节点编号最小的那个点。
题意:找到树的重心,然后求所有点到树的重心的距离和。
思路:树形dp根据重心的性质找到重心,然后再跑dfs求距离和。
#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
struct node
int x,to;
;
node e[maxn];
int idx=0;
int n,h[maxn],f[maxn],siz[maxn];
void add(int a,int b)
e[idx].x=b,e[idx].to=h[a],h[a]=idx++;
void dfs(int x,int fa)
siz[x]=1;
for(int i=h[x];i!=-1;i=e[i].to)
int j=e[i].x;
if(j==fa)continue;
dfs(j,x);
siz[x]+=siz[j];
f[x]=max(f[x],siz[j]);//最大的儿子子树
f[x]=max(f[x],n-siz[x]);//与dfs的上面部分取max,因为上面部分也是子树
int res=0;
void dfs1(int x,int fa,int step)
res+=step;
for(int i=h[x];i!=-1;i=e[i].to)
int j=e[i].x;
if(j==fa)continue;
dfs1(j,x,step+1);
int main()
memset(h,-1,sizeof h);
scanf("%d",&n);
int a,b;
for(int i=1;i<n;i++)
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
dfs(1,-1);//找重心
int pos=1;
for(int i=2;i<=n;i++)
if(f[i]<f[pos])//拿掉该点后子树最小的为重心
pos=i;
dfs1(pos,-1,0);
cout<<pos<<" "<<res<<endl;
以上是关于P1395 会议(树的重心)的主要内容,如果未能解决你的问题,请参考以下文章