Garland

Garland

https://ac.nowcoder.com/acm/problem/111886

题意

你有一颗个节点的树,每个节点有一个点权,现在要求将这一棵树拆为三棵子树,子树的权值之和相等。

思路

由于点权之和确定,那么每棵子树的权值之和就一定。那么我们只需要搜索,当当前记录的权值之和为所有点权值的三分之一时,记录下答案和答案个数。当答案个数小于时,输出

代码

#include<bits/stdc++.h>
#define ll long long
const int N=1e6+5,INF=0x3f3f3f3f,mod=998244353;
using namespace std;

int n,cnt,rt,py,sum;
int head[N],a[N];
struct node
{
    int to,nxt;
}e[N<<1];
vector<int > ans;

inline int read()
{
    register int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}

void add(int u,int v)
{
    e[++cnt].nxt=head[u];
    e[cnt].to=v;
    head[u]=cnt;
}

int dfs(int fa,int now)
{
    int tot=a[now];
    for(int i=head[now];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa)    continue ;
        tot+=dfs(now,to);
    }
    if(tot*3==sum)
    {
        ans.push_back(now);
        tot=0;
    }
    if(ans.size()==3)
    {
        for(int i=0;i<ans.size()-1;i++) 
            printf("%d ",ans[i]);
        exit(0);
    }
     return tot;
}


int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        int u;
        u=read();a[i]=read();
        sum+=a[i];
        add(u,i);add(i,u);
        if(!u)    rt=i;
    }
    dfs(0,rt);
    printf("-1");
    return 0;
}
全部评论

相关推荐

2024-12-13 17:03
门头沟学院 Java
点赞 评论 收藏
分享
评论
3
2
分享

创作者周榜

更多
牛客网
牛客企业服务