2018“百度之星”程序设计大赛 - 复赛-1001-没有兄弟的舞会(set)

没有兄弟的舞会

Accepts: 926

Submissions: 2432

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

Problem Description

度度熊、光羽、带劲三个人是好朋友。

度度熊有一棵nnn个点的有根树,其中1号点为树根。除根节点之外,每个点都有父节点,记iii号点的父节点为fa[i]fa[i]fa[i]。

度度熊称点iii和点jjj是兄弟(其中i≠ji \neq ji≠j)当且仅当fa[i]=fa[j]fa[i]=fa[j]fa[i]=fa[j]。

第iii个点的权值为AiA_iA​i​​。现要求选出一个点集,该点集合法当且仅当点集中至多只有一对兄弟

度度熊想知道,在所有可行的点集中,权值和最大以及最小的点集权值和分别是多少?

Input

第一行一个数,表示数据组数TTT。

每组数据第一行一个整数nnn;第二行n−1n-1n−1个数,表示fa[2],fa[3],..,fa[n]fa[2],fa[3],..,fa[n]fa[2],fa[3],..,fa[n];第三行nnn个数,表示AiA_iA​i​​。

数据组数T=100,满足:

  • 1≤n≤1051 \le n \le 10^51≤n≤10​5​​
  • −109≤Ai≤109-10^9 \le A_i \le 10^9−10​9​​≤A​i​​≤10​9​​
  • 1≤fa[i]<i1 \le fa[i] < i1≤fa[i]<i

其中90%的数据满足n≤1000n \le 1000n≤1000。

Output

每组数据输出一行,每行包含两个数,分别表示权值和的最大值最小值

Sample Input

Copy

2
5
1 1 2 2 
-4 -4 -1 -2 -5 
5
1 1 3 2 
-1 -4 2 0 -2 

Sample Output

Copy

0 -15
2 -7

Statistic | Submit | Clarifications | Back

题解:将每个元素加入到对应父亲的set里,然后访问最大最小值即可。。。水题一道

#include<set>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define mod 1000000007
ll n,a[100005],ans1=0,ans2=0;
int f[100005];
set<ll>s[100005];set<ll>::iterator it;
int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans1=0,ans2=0;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
            s[i].clear();
        for(int i=2;i<=n;i++)
            scanf("%d",&f[i]);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]),s[f[i]].insert(a[i]);
        for(int i=0;i<=n;i++)
        {
            if(s[i].empty()==0)
            {
                it=s[i].end();it--;
                if((*it)>0) ans2+=(*it),s[i].erase(it);
            }
            if(s[i].empty()==0)
            {
                it=s[i].begin();
                if((*it)<0) ans1+=(*it),s[i].erase(it);
            }
        }
        ll mx=0,mn=0;
        for(int i=0;i<=n;i++)
        {
            if(s[i].empty())
                continue;
            it=s[i].begin();
            mn=min(mn,(*it));
            it=s[i].end();it--;
            mx=max(mx,(*it));
        }
        printf("%lld %lld\n",ans2+mx,ans1+mn);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/haut_ykc/article/details/81810584