CSU 1908: The Big Escape

本文介绍了一种解决树形结构监狱中囚犯逃脱问题的算法。通过计算最大子树节点数量,确定最后一名囚犯逃脱所需时间。文章提供了具体实现代码,采用并查集结构进行节点合并与查询。

Description

There is a tree-like prison. Expect the root node, each node has a prisoner, and the root node is the only exit. Each node can accommodate a large number of prisoners, but each edge per minute only one prisoner can pass.
Now, the big escape begins, every prisoner wants to escape to the exit.Do you know when the last one escapes from the prison.

Input

There are lots of case.
For each test case.The first line contains two integers n,m(n<=100000, 1<=m<=n), which indicates the number of nodes and the root node.
The next n-1 lines describe the tree.

Output

For each test case, you output one line “Case #%d:%d”

Sample Input

10 2
1 2
2 3
2 4
2 5
1 6
5 7
3 8
2 9
2 10

Sample Output

Case #1:2

Hint

 

一道不是很难的题目。树形结构的监狱,只需要找到最大的子树的结点的数量即可。但是题目中对于树的描述让我很迷惑,果然是菜的明明白白,连题目都看不懂。题目中输入n,m之后应该对于树的描述在我理解看来:若一行数据中的两个数存在根节点,则另外一个点为根节点的子节点,如果不存在根节点,那么默认左边的数作为父节点,右边的数作为子节点(这一点在数据(1,2)不适合,但是符合上一点)。

由于只要到达了根节点,则逃亡成功,因此根节点的所有子节点(第二层的结点)的人是可以同时出去的,但是当第二层以及第二层以下的犯人最终都会到达第二层,并在第二层等待,依次出去,因此计算最大子树的节点数即可。

 

代码如下:

 

#include <bits/stdc++.h>
int n,m,i,x,y,fa[100005],sum[100005];  //sum[i]代表以结点i为根节点的树的所有节点结点的数量,fa[i]代表结点i的父节点
int Case=1;

//并查集查询结点k的最高层的祖先节点
int findfa(int k)
{
    return fa[k]==k?k:findfa(fa[k]);
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++)   //每个节点作为单独的树,生成一个森林
        {
            fa[i]=i;
            sum[i]=1;
        }
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            if(x!=m&&y!=m) //生成各个子树,不需要处理根节点
            {
                int xf=findfa(x),yf=findfa(y);
                if(xf!=yf)
                {
                    fa[yf]=xf;
                    sum[xf]+=sum[yf];
                }
            }
        }
        int ans=0;
        for(i=1;i<=n;i++)  //找所有子树中的最大节点数
            if(i!=m&&fa[i]==i)  ans=ans>sum[i]?ans:sum[i];
        printf("Case #%d:%d\n",Case++,ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值