Jerry的题

单点时限: 1.0 sec
内存限制: 512 MB

Jerry给Tom出了一道题,题目是这样的:
**给出一棵n个节点的树,节点编号为1-n(根节点编号为1),每一个节点作为根节点与他所有的子孙节点形成一棵子树,而这棵子树包含节点的数量,称作子树的Size。

例如:

1─2─4─5
└─3

其中节点5的子树只包括节点5,Size = 1。节点4的子树包括节点4,5,Size = 2。节点1的子树包括节点1,2,3,4,5,Size = 5。

求以所有节点为根的子树的Size之和。上面例子中,节点1到5,对应的Size分别为5,3,1,2,1,所有Size的和 = 5 + 3 + 1 + 2 + 1 = 12

输入格式
第一行:1个数n(1 < n <= 10000),表示树的节点数量。
后面n-1行:每行2个数x y,表示节点x是节点y的父节点(1 <= x, y <= n)。

输出格式
输出1个数,表示以所有节点为根的子树的Size之和。

样例
input
4
1 2
1 3
2 4
output
8

思路:

首先用vector pair把图存进来,然后暴力枚举对每一个点进行bfs,找他的子树的size;再加上记忆化搜索,就不会超时了!

AC代码:

#include <bits/stdc++.h>

using namespace std;

vector<pair<int,int> > v[10010];
int dp[10010];
int ans;
int bfs(int n)
{
    ans=1;
    queue<int> q;
    int h=n;
    q.push(h);
    while(!q.empty())
    {
        h=q.front();
        q.pop();
        pair<int,int> n;
        for(int i=0;i<v[h].size();i++)
        {
            n=v[h][i];
            if(dp[n.first]>0&&n.second==1)
            {
                ans+=dp[n.first];
                continue;
            }
            if(n.second==1)
            {
                ans++;
                q.push(n.first);
            }
        }
    }
    return ans;
}
int main()
{
    int n;
    cin >>n;
    int x,y;
    for(int i=1;i<n;i++)
    {
        cin >>x>>y;
        v[x].push_back(make_pair(y,1));
        v[y].push_back(make_pair(x,-1));
    }
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        dp[i]=bfs(i);
        sum+=dp[i];
    }
    cout <<sum<<endl;
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值