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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/imzxww/article/details/81879289

http://acm.hdu.edu.cn/showproblem.php?pid=6409

思路:

这题直接暴力找每个点的子节点的最大值、最小值、次大值和次小值,求最大值时只加大于0的,最小值只加小于0 的。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
vector<int>e[maxn];
struct node
{
    int to,next;
}edge[maxn*2];
int head[maxn],tot;
ll w[maxn];
ll dp[maxn][2];
ll dp1[maxn][2];
void addedge(int u,int v)
{
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void init()
{
    memset(head,-1,sizeof(head));
    memset(dp,0,sizeof(dp));
    memset(dp1,0,sizeof(dp1));
    tot=0;
}
void dfs(int u,int pre)
{
    dp[u][0]=-inf,dp[u][1]=-inf;
    dp1[u][0]=inf,dp1[u][1]=inf;
    for(int i=head[u];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(v==pre)continue;
        if(w[v]>dp[u][0])
        {
            dp[u][1]=dp[u][0];
            dp[u][0]=w[v];
        }
        else if(w[v]==dp[u][0]||w[v]>dp[u][1])
        {
            dp[u][1]=w[v];
        }
        if(w[v]<dp1[u][0])
        {
            dp1[u][1]=dp1[u][0];
            dp1[u][0]=w[v];
        }
        else if(w[v]==dp1[u][0]||w[v]<dp1[u][1])
        {
            dp1[u][1]=w[v];
        }
        //printf("%lld %lld %lld %lld\n",dp[u][0],dp[u][1],dp1[u][0],dp1[u][1]);
        dfs(v,u);
    }

}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        init();
        int u;
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&u);
            addedge(u,i);
            addedge(i,u);
        }

        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&w[i]);
        }
        dfs(1,-1);
        dp[0][0]=w[1];
        dp1[0][0]=w[1];
        ll ma=0;
        ll ans=0;
        for(int i=0;i<=n;i++)
        {
            if(dp[i][0]>0)
            {
                ans+=dp[i][0];
                ma=max(dp[i][1],ma);
            }
        }
        ans+=ma;
        ll mi=0;
        ll ans1=0;
        for(int i=0;i<=n;i++)
        {
            if(dp1[i][0]<0)
            {
                ans1+=dp1[i][0];
                mi=min(dp1[i][1],mi);
            }
        }
        ans1+=mi;
        printf("%lld %lld\n",ans,ans1);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/imzxww/article/details/81879289