POJ 1655

xiaoxiao2021-02-28  97

题意:求出树重心的编号(如果有多个重心则取编号最小的那个),以及以重心为根子树大小的最小值

分析:求重心裸题,其实就是找到一个点作为根,使各子树大小size的最大值最小。dfs即可求解。

技能:  t=max(t,n-size[u]);   注意这句话不能漏,可以理解比较形象地为子树不一定在下面,还可能在上面。

代码:

#include<cstdio> #include<cstring> using namespace std; #define rep(i,j,k) for (int i=j;i<=k;++i) #define dep(i,j,k) for (int i=j;i>=k;--i) #define to e[i].v #define Cl(a) memset(a,0,sizeof(a)) #define inf 1234567890 #define max(a,b) a>b? a:b #define N 20010 struct node{     int v,next; }e[N*2]; int head[N],size[N],id,n,ans,s;   int read() {     int f=1,x=0;char ch=getchar();     for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;     for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';     return x*f; } void add(int u,int v) {e[id].v=v; e[id].next=head[u]; head[u]=id++;} void dfs(int u,int lastfa) {     size[u]=1;     int t=0;     for (int i=head[u];i;i=e[i].next)     if (to^lastfa)     {         dfs(to,u);         size[u]+=size[to];         t=max(t,size[to]);     }     t=max(t,n-size[u]);     if (t<s||t==s && u<ans)     {         ans=u;         s=t;     } } int main() {     int t=read();     for (;t--;)     {         n=read(); id=1; Cl(head); Cl(size);         rep(i,1,n-1) {int u=read(),v=read(); add(u,v); add(v,u);}         ans=inf; s=inf;         dfs(1,1);         printf("%d %d\n",ans,s);     }     return 0; }

转载请注明原文地址: https://www.6miu.com/read-80160.html

最新回复(0)