zoukankan      html  css  js  c++  java
  • Codeforces Round #398 (Div. 2) C. Garland —— DFS

    题目链接:http://codeforces.com/contest/767/problem/C


    题解:类似于提着一串葡萄,用剪刀剪两条藤,葡萄分成了三串。问怎样剪才能使三串葡萄的质量相等。

    首先要做的就是统计葡萄的总质量tot。之后就是找到两子串质量为(tot/3)的葡萄(如果除不尽,则必定找不到),那么剩下的就是dfs搜索了。

    我一开始的做法是先建一棵记录子树质量和的树,然后再从上往下dfs,如果找到了,就把它剪掉。后来发现被剪掉的那一串可能就含有两串质量为(tot/3)的葡萄(这里质量 可为负数), 所以这种方法行不通。

    那么正确的做法是先深入到最底层(叶子结点),然后再从下往上搜索,这个过程与建树的过程是一致的。所以可以将两个过程合并在一起。


    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<queue>
     7 #include<vector>
     8 #include<map>
     9 #include<string>
    10 #include<set>
    11 #define LL long long
    12 #define MAX(a,b) (a>b?a:b)
    13 #define MIN(a,b) (a<b?a:b)
    14 #define INF 0x7fffffff
    15 #define LNF ((1LL<<62)-1)
    16 #define maxn 200010
    17 
    18 using namespace std;
    19 
    20 int n, tot = 0,cnt = 0, sum[1000005], vis[1000005];
    21 vector<int>child[1000005];
    22 int ans[5];
    23 
    24 int build(int rt)
    25 {
    26     vis[rt] = 1;
    27     int m = child[rt].size();
    28     for(int i = 0; i<m; i++)
    29     {
    30         if(!vis[child[rt][i]])
    31         sum[rt] += build(child[rt][i]);
    32 
    33         if(cnt==2)
    34             return 0;
    35     }
    36 
    37     if(sum[rt]==tot)
    38     {
    39         ans[cnt++] = rt;
    40         return 0;
    41     }
    42     else return sum[rt];
    43 }
    44 
    45 int main()
    46 {
    47     int rt,v;
    48     scanf("%d",&n);
    49     for(int i = 1; i<=n; i++)
    50     {
    51         scanf("%d%d",&v,&sum[i]);
    52 
    53         if(v)
    54         child[i].push_back(v);
    55         child[v].push_back(i);
    56 
    57         tot += sum[i];
    58         if(!v) rt = i, vis[rt] = 1;
    59     }
    60 
    61     if(tot%3)
    62     {
    63         puts("-1");
    64         return 0;
    65     }
    66 
    67     tot /= 3;
    68     int m = child[rt].size();
    69     for(int i = 0; i<m; i++)
    70     {
    71         build(child[rt][i]);
    72         if(cnt==2) break;
    73     }
    74 
    75     if(cnt==2)
    76         printf("%d %d
    ",ans[0],ans[1]);
    77     else
    78         puts("-1");
    79 
    80 }
    View Code
  • 相关阅读:
    封装cookie
    敏感词过滤
    面向对象改成选项卡
    正则表达式
    cookie
    DOM
    系统对象
    cookie记录用户名
    6个原则
    23中设计模式
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538737.html
Copyright © 2011-2022 走看看