1991【19CSPS提高组】树的重心 信奥赛Kirito(本人)

本文介绍了一种关于树的重心的算法问题,重点讲解如何计算删除特定边后得到的子树重心编号之和。通过递归深度优先搜索实现,文章详细展示了算法流程与核心代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1991:【19CSPS提高组】树的重心

【题目描述】
小简单正在学习离散数学,今天的内容是图论基础,在课上他做了如下两条笔记:

  1. 一个大小为 nn 的树由 nn 个结点与 n−1n−1 条无向边构成,且满足任意两个结点间有且仅有一条简单路径。在树中删去一个结点及与它关联的边,树将分裂为若干个子树;而在树中删去一条边(保留关联结点,下同),树将分裂为恰好两个子树。

  2. 对于一个大小为 nn 的树与任意一个树中结点 cc,称 cc 是该树的重心当且仅当在树中删去 cc 及与它关联的边后,分裂出的所有子树的大小均不超过⌊n2⌋⌊n2⌋其中 ⌊x⌋⌊x⌋是下取整函数)。对于包含至少一个结点的树,它的重心只可能有 11 或 22 个。

课后老师给出了一个大小为 nn 的树 SS,树中结点从 1∼n1∼n 编号。小简单的课后作业是求出 SS 单独删去每条边后,分裂出的两个子树的重心编号和之和。即:

∑(u,v)∈E(∑1≤x≤n,且x号点是S′u的重心x+∑1≤y≤n,且y号点是S′v的重心y)
∑(u,v)∈E(∑1≤x≤n,且x号点是Su′的重心x+∑1≤y≤n,且y号点是Sv′的重心y)
上式中,EE 表示树 SS 的边集,(u,v)(u,v) 表示一条连接 uu 号点和 vv 号点的边。S′uSu′与 S′vSv′分别表示树 SS 删去边 (u,v)(u,v) 后,uu 号点与 vv 号点所在的被分裂出的子树。

小简单觉得作业并不简单,只好向你求助,请你教教他。

【输入】
本题输入包含多组测试数据。

第一行一个整数 TT 表示数据组数。

接下来依次给出每组输入数据,对于每组数据:

第一行一个整数 nn 表示树 SS 的大小。

接下来 n−1n−1 行,每行两个以空格分隔的整数 ui,viui,vi,表示树中的一条边 (ui,vi)(ui,vi)。

【输出】
共 TT 行,每行一个整数,第 ii 行的整数表示:第 ii 组数据给出的树单独删去每条边后,分裂出的两个子树的重心编号和之和。

【输入样例】
2
5
1 2
2 3
2 4
3 5
7
1 2
1 3
1 4
3 5
3 6
6 7
【输出样例】
32
56
【提示】
【样例 1 解释】

对于第一组数据:

删去边 (1, 2),1 号点所在子树重心编号为 {1},2 号点所在子树重心编号为 {2, 3}。

删去边 (2, 3),2 号点所在子树重心编号为 {2},3 号点所在子树重心编号为 {3, 5}。

删去边 (2, 4),2 号点所在子树重心编号为 {2, 3},4 号点所在子树重心编号为 {4}。

删去边 (3, 5),3 号点所在子树重心编号为 {2},5 号点所在子树重心编号为 {5}。

因此答案为 1 + 2 + 3 + 2 + 3 + 5 + 2 + 3 + 4 + 2 + 5 = 32。

【数据范围】

测试点编号 n = 特殊性质
1 ∼ 2 7 无
3 ∼ 5 199
6 ∼ 8 1999
9 ∼ 11 49991 A
12 ∼ 15 262143 B
16 99995 无
17 ∼ 18 199995
19 ∼ 20 299995
表中特殊性质一栏,两个变量的含义为存在一个 1∼n1∼n 的排列 pi(1≤i≤n)pi(1≤i≤n),使得:

A:树的形态是一条链。即 ∀1≤i<n∀1≤i<n,存在一条边 (pi,pi+1)(pi,pi+1)。

B:树的形态是一个完美二叉树。即 ∀1≤i≤n−12∀1≤i≤n−12 ,存在两条边 (pi,p2i)(pi,p2i) 与 (pi,p2i+1)(pi,p2i+1)。

对于所有测试点:1≤T≤5,1≤ui,vi≤n1≤T≤5,1≤ui,vi≤n。保证给出的图是一个树。

英文翻译:[Title Description]
Xiaojian is learning discrete mathematics. Today’s content is the basis of graph theory. In class, he made the following two notes:

  1. A tree of size NN consists of NN nodes and N − 1n − 1 undirected edge, and there is only one simple path between any two nodes. If a node and its associated edge are deleted in the tree, the tree will be split into several subtrees; if an edge is deleted from the tree (keep the associated node, the same below), the tree will split into exactly two subtrees.
  2. For a tree of size NN and any node CC in a tree, CC is called the center of gravity of the tree if and only if CC and its associated edges are deleted in the tree, the size of all the subtrees split up does not exceed ⌊ N2 ⌋ ⌊ N2 ⌋ where ⌊ x ⌋ is the lower integral function). For a tree with at least one node, it can only have 11 or 22 barycenters.
    After class, the teacher gave a tree SS with the size of NN. The nodes in the tree were numbered from 1 ∼ N1 ∼ n. Cut out the sum of the two sub trees of each SS after class. Namely:
    Σ (U, V) ∈ e (∑ 1 ≤ x ≤ n, and point x is the center of gravity of s ′ u, x + ∑ 1 ≤ y ≤ n, and point y is the center of gravity of s ′ V)
    Σ (U, V) ∈ e (∑ 1 ≤ x ≤ n, and point x is the center of gravity of Su ′, x + ∑ 1 ≤ y ≤ n, and point y is the center of gravity of SV ′)
    In the above formula, EE is the edge set of SS, and (U, V) (U, V) is an edge connecting UU point and VV point. S ′ usu ′ and s ′ VSV ′ denote the subtree of point UU and point VV in SS after deleting edge (U, V) (U, V), respectively.
    Xiaojian thinks the homework is not simple, so she has to ask you for help and teach him.
    [input]
    The input of this question contains multiple sets of test data.
    In the first line, an integer TT represents the number of data groups.
    Next, the input data of each group are given in turn
    In the first row, an integer NN represents the size of the tree SS.
    Next, n − 1n − 1 rows, each with two integers UI, viui, VI separated by spaces, representing an edge (UI, VI) (UI, VI) in the tree.
    [output]
    There are TT rows in total, each row is an integer, and the integer of row II represents the sum of the barycenter numbers of the two split subtrees after deleting each edge of the tree given by group II data.
    [Title Description]
    Xiaojian is learning discrete mathematics. Today’s content is the basis of graph theory. In class, he made the following two notes:
  3. A tree of size NN consists of NN nodes and N − 1n − 1 undirected edge, and there is only one simple path between any two nodes. If a node and its associated edge are deleted in the tree, the tree will be split into several subtrees; if an edge is deleted from the tree (keep the associated node, the same below), the tree will split into exactly two subtrees.
  4. For a tree of size NN and any node CC in a tree, CC is called the center of gravity of the tree if and only if CC and its associated edges are deleted in the tree, the size of all the subtrees split up does not exceed ⌊ N2 ⌋ ⌊ N2 ⌋ where ⌊ x ⌋ is the lower integral function). For a tree with at least one node, it can only have 11 or 22 barycenters.
    After class, the teacher gave a tree SS with the size of NN. The nodes in the tree were numbered from 1 ∼ N1 ∼ n. Cut out the sum of the two sub trees of each SS after class. Namely:
    Σ (U, V) ∈ e (∑ 1 ≤ x ≤ n, and point x is the center of gravity of s ′ u, x + ∑ 1 ≤ y ≤ n, and point y is the center of gravity of s ′ V)
    Σ (U, V) ∈ e (∑ 1 ≤ x ≤ n, and point x is the center of gravity of Su ′, x + ∑ 1 ≤ y ≤ n, and point y is the center of gravity of SV ′)
    In the above formula, EE is the edge set of SS, and (U, V) (U, V) is an edge connecting UU point and VV point. S ′ usu ′ and s ′ VSV ′ denote the subtree of point UU and point VV in SS after deleting edge (U, V) (U, V), respectively.
    Xiaojian thinks the homework is not simple, so she has to ask you for help and teach him.
    [input]
    The input of this question contains multiple sets of test data.
    In the first line, an integer TT represents the number of data groups.
    Next, the input data of each group are given in turn
    In the first row, an integer NN represents the size of the tree SS.
    Next, n − 1n − 1 rows, each with two integers UI, viui, VI separated by spaces, representing an edge (UI, VI) (UI, VI) in the tree.
    [output]
    There are TT rows in total, each row is an integer, and the integer of row II represents the sum of the barycenter numbers of the two split subtrees after deleting each edge of the tree given by group II data.
    不想做解析了,没什么可讲的,懂得都懂
    吐槽一下下,一年比一年难了。1990过不了,九敏!
    Code
    #include
    #include
    #include
    using namespace std;
    #define maxn 300010
    #define MS(f) memset(f,0,sizeof(f))

int T,n,a,b;long long ans;
struct edge{int y,next;}e[maxn<<1];
int first[maxn],len;
void buildroad(int x,int y){e[++len]=(edge){y,first[x]};first[x]=len;}
int s[maxn],g[maxn],rt;
void dfs1(int x,int fa)
{
s[x]=1;g[x]=0;bool v=true;
for(int i=first[x];i;i=e[i].next)
{
int y=e[i].y;if(y==fa)continue;
dfs1(y,x);s[x]+=s[y];g[x]=max(g[x],s[y]);
if(s[y]>(n>>1))v=false;
}
if(n-s[x]>(n>>1))v=false; if(v)rt=x;
}
int tr1[maxn],tr2[maxn];
void add(int *tr,int x,int y){for(x+=2;x<=n+2;x+=(x&-x))tr[x]+=y;}
int sum(int *tr,int x){int re=0;for(x+=2;x;x-=(x&-x))re+=tr[x];return re;}
int getsum(int *tr,int x,int y){return sum(tr,y)-sum(tr,x-1);}
bool Big[maxn];
void dfs2(int x,int fa)
{
add(tr1,s[fa],-1);add(tr1,n-s[x],1);Big[x]|=Big[fa];

if(x!=rt)ans+=1llx(getsum(tr1,n-2s[x],n-2g[x])+getsum(tr2,n-2s[x],n-2g[x]));
if(x!=rt)ans+=1llrt(s[x]<=n-2*(Big[x]?b:a));
add(tr2,s[x],1);
for(int i=first[x];i;i=e[i].next)if(e[i].y!=fa)dfs2(e[i].y,x);
if(x!=rt)ans-=1llxgetsum(tr2,n-2s[x],n-2g[x]);
add(tr1,s[fa],1);add(tr1,n-s[x],-1);
}

int main()
{
scanf("%d",&T);while(T–)
{
scanf("%d",&n);MS(first);len=ans=0;
for(int i=1,x,y;i<n;i++)scanf("%d %d",&x,&y),
buildroad(x,y),buildroad(y,x); dfs1(1,0);dfs1(rt,0);
MS(tr1);MS(tr2);for(int i=1;i<=n;i++)add(tr1,s[i],1);
a=b=0;for(int i=first[rt];i;i=e[i].next)
if(s[e[i].y]>=a)b=a,a=s[e[i].y];else if(s[e[i].y]>=b)b=s[e[i].y];
MS(Big);for(int i=first[rt];i;i=e[i].next)Big[e[i].y]=(s[e[i].y]==a);
dfs2(rt,0);printf("%lld\n",ans);
}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值