CodeForces 767C Garland

树形$dp$。

先看权值之和是否为$3$的倍数,如果不是则一定无解。

如果是$3$的倍数,可以分两次去切。每次一个节点,要求这个节点不是根,并且的子树权值和为$sum/3$,又要是深度最深的。

找不到两个依然是无解,否则就有解。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0);
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - ‘0‘;
        c = getchar();
    }
}

int n,root,c[1000010],p[1000010],sum,ans1,ans2;
vector<int >v[1000010];
int flag1,flag2;

void dfs1(int x)
{
    c[x]=p[x];
    for(int i=0;i<v[x].size();i++)
    {
        dfs1(v[x][i]); if(flag1) return ;
        c[x]+=c[v[x][i]];
    }
    if(x!=root&&c[x]==sum/3)
    {
        flag1=1;
        ans1=x;
    }
}

void dfs2(int x)
{
    c[x]=p[x];
    for(int i=0;i<v[x].size();i++)
    {
        if(v[x][i]==ans1) continue;
        dfs2(v[x][i]); if(flag2) return ;
        c[x]+=c[v[x][i]];
    }
    if(x!=root&&c[x]==sum/3)
    {
        flag2=1;
        ans2=x;
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int fa; scanf("%d%d",&fa,&p[i]);
        sum=sum+p[i];
        if(fa==0) root=i;
        else v[fa].push_back(i);
    }

    if(sum%3!=0)
    {
        printf("-1\n");
        return 0;
    }

    dfs1(root);

    if(flag1==0)
    {
        printf("-1\n");
        return 0;
    }

    memset(c,0,sizeof c);
    dfs2(root);

    if(flag2==0)
    {
        printf("-1\n");
        return 0;
    }

    else
    {
        printf("%d %d\n",ans1,ans2);
    }

    return 0;
}
时间: 2024-10-26 19:47:51

CodeForces 767C Garland的相关文章

Codeforces 767C. Garland (dfs)

题目链接: http://codeforces.com/problemset/problem/767/C 题意: 一棵树,每个节点有一个权值t,把它分成三部分,每部分要求权值和相等. 思路: 由于子树的子树里再出现等于sum/3的情况,那么dp[u]=0,就可以很好的避免计算情况了 dfs  第一找出来一个sum/3,然后子树结果清零,然后再dfs一次,直接忽视掉前一个sum/3,找出第二个sum/3,如果能找出来就输出,不能就-1. 还有一种笨写法.(傻逼的我调了半辈子) 代码: 代码一: #

CodeForces 408B Garland

Problem Link 1 /* 2 题目大意: 3 第一行输入纸张的类型和张数,第二行输入纸张类型 4 求可能拼出的最大面积:如果第二行中有第一行所不具备的纸张类型,则输出-1 5 思路 : 我用了两个长度为 25 的 int 型数组来记录输入的字母的个数,然后逐一比较即可: 6 */ 7 #include <iostream> 8 #include<string.h> 9 #include<cstdio> 10 using namespace std; 11 12

B类-Codeforces Round #535 (Div. 3)C. Nice Garland

Codeforces Round #535 (Div. 3)C. Nice Garland 题意: 由'R', 'G' and 'B' 三个字母组成的一个字符串,每两个相同的字母需要相差3,找出最小需要交换次数. 分析: 这个字符串的长度大于等于3的时候,一定是RBG这三个字符的某一个排列的循环.RBG一共最多有6种排列方式{"RGB","RBG","BGR","BRG","GRB","GBR&q

Codeforces 758B:Blown Garland(模拟)

http://codeforces.com/problemset/problem/758/B 题意:给出一个字符串,每4个位置对应一个颜色,如果为‘!’的话,代表该灯泡是坏的,问最后每个颜色坏的灯泡的数目. 思路:题意实在挺难懂的(可能我到现在还没看懂).看样例看了好久才看出来.例如最后一个样例“!GB!RG!Y!”:可以拆分成"!GB!”,"RG!Y","!",R只在第一个位置出现,说明R是在第一个位置的,以此类推,G是在第二个位置,B是在第三个位置,Y

Codeforces 392 B Blown Garland

题意:输入是由连续的RYGB和字符!组成的字符串,R代表红灯,Y代表黄灯,G代表绿灯,B代表蓝灯.简而言之,就是给定的字符串保证了下标对4取余相同的灯颜色都相同,但是有的地方为'!'代表这个灯坏了,然后分别输出坏了的红.蓝.黄.绿灯的数量. 分析:因为下标对4取余相同的灯颜色都相同,所以确定了前四个灯的颜色,后面的灯都是前四个灯颜色的不断循环,两个map映射一下就可以了. #include<bits/stdc++.h> #define Min(a, b) ((a < b) ? a : b

codeforces 140E.New Year Garland

传送门: 解题思路: 要求相邻两行小球颜色集合不同,并且限制行内小球相邻不同. 由此可得:每行小球排列都是独立与外界的, 所以答案应该是对于所有行的颜色集合分类,在将行内的答案乘到上面. 先考虑如何分类: 我们可以确定对于每行所取的颜色种类$x=|S|$, 若相邻两行$i,j$,其$x_i!=x_j$,那么一定是合法的,有$C_m^x$种选择方法. 而对于相邻两行$x_i=x_j$,对于行$i$的一种方案,只有一种可能使得$S_i=S_j$, 所以可以使用容斥来计算答案 综上所述,按照每行的颜色

Codeforces Round #535 (Div. 3) 1108C - Nice Garland

#include <bits/stdc++.h> using namespace std; int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); #endif int n; string s; cin >> n >> s; vector<in

Codeforces Round #535 (Div. 3) 题解

Codeforces Round #535 (Div. 3) 题目总链接:https://codeforces.com/contest/1108 太懒了啊~好久之前的我现在才更新,赶紧补上吧,不能漏掉了. A. Two distinct points 题意: 给出两个区间的左右边界,输出两个数,满足两个数分别在两个区间内且这两个数不相等. 题解: 直接输出左端点然后判断一下就行了. 代码如下: #include <bits/stdc++.h> using namespace std; type

Educational Codeforces Round 79 (Rated for Div. 2)

A. New Year Garland (CF 1279 A) 题目大意 给定红绿蓝三种颜色灯的数量,问能否摆成一排,使得相邻颜色不相同. 解题思路 植树问题.考虑数量最多为\(n\)的颜色的灯俩俩不相邻,那么其他颜色的灯的数量和要大于\(n-1\)即可,大过\(n-1\)的灯直接插到里面就好了. 神奇的代码 #include <bits/stdc++.h> #define MIN(a,b) ((((a)<(b)?(a):(b)))) #define MAX(a,b) ((((a)>