• Codeforces Round #398 (Div. 2) C. Garland DFS


    C. Garland

    链接:

    http://codeforces.com/contest/767/problem/C

    题意:

    给你一颗树,其中包含N个点,让你将这颗树剪去两条边,使得变成三部分,要求三部分的权值和相等。

    题解:

    1、我们设定sum【i】表示以i作为根的子树权值和。

    那么过程维护,sum【i】+=sum【v】;

    2、如果全部点的权值和不是3的倍数,那么显然无解,否则考虑:

    ①遇到了一个点u,此时sum【u】=tot/3;那么这个点就可以将其拆除出来。

    ②将一个点拆出来的同时,设定sum【u】=0;回溯,继续找下一个tot/3

    ③如果过程中遇到了两个sum【u】=tot;此时存在解。

    代码:

     1 #include <map>
     2 #include <set>
     3 #include <cmath>
     4 #include <queue>
     5 #include <stack>
     6 #include <cstdio>
     7 #include <string>
     8 #include <vector>
     9 #include <cstring>
    10 #include <iostream>
    11 #include <algorithm>
    12 #include <functional>
    13 using namespace std;
    14 #define rep(i,a,n) for (int i=a;i<=n;i++)
    15 #define per(i,a,n) for (int i=n;i>=a;i--)
    16 #define pb push_back
    17 #define mp make_pair
    18 #define all(x) (x).begin(),(x).end()
    19 #define fi first
    20 #define se second
    21 #define SZ(x) ((int)(x).size())
    22 typedef vector<int> VI;
    23 typedef long long ll;
    24 typedef pair<int, int> PII;
    25 const ll mod = 1000000007;
    26 // head
    27 
    28 const int maxn = 1e6 + 7;
    29 VI tree[maxn];
    30 int val[maxn];
    31 int sum[maxn];
    32 int n, tot, ans1, ans2, root;
    33 
    34 void dfs(int u)
    35 {
    36     sum[u] = val[u];
    37     for (int i = 0; i<tree[u].size(); i++){
    38         int v = tree[u][i];
    39         dfs(v);
    40         sum[u] += sum[v];
    41     }
    42     if (sum[u] == tot){
    43         if (u == root) return;
    44         if (ans1 == -1){
    45             ans1 = u;
    46             sum[u] = 0;
    47         }
    48         else if (ans2 == -1){
    49             ans2 = u;
    50             sum[u] = 0;
    51         }
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     cin >> n;
    58     rep(i, 1, n) {
    59         int a;
    60         scanf("%d%d", &a, val + i);
    61         tot += val[i];
    62         if (a == 0) {
    63             root = i; 
    64             continue;
    65         }
    66         tree[a].pb(i);
    67     }
    68     if (tot % 3) return 0 * printf("-1
    ");
    69     tot /= 3;
    70     ans1 = ans2 = -1;
    71     dfs(root);
    72     if (ans1 == -1 || ans2 == -1) cout << -1 << endl;
    73     else cout << ans1 << " " << ans2 << endl;
    74     return 0;
    75 }
  • 相关阅读:
    python 读取邮件
    windows 关于时间的计算
    python 发送 smtp
    常用HTML富文本编辑器
    数据库设计:用户登录系统数据库表设计
    在当前页面打开一个固定的窗口(页面):这种方式弹出来的窗口进行表单提交可更新父类窗口
    后台模板
    springboot/springmvc转换器
    设计模式目录
    组合条件分页查询
  • 原文地址:https://www.cnblogs.com/baocong/p/6418904.html
Copyright © 2020-2023  润新知