zoukankan      html  css  js  c++  java
  • [APIO2007] 风铃

    题目链接

    可能是个树上 DP?指针真好玩 23333。

    首先对于所有玩具如果有深度差超过 1 的就是无解(在这里贡献 WA * 3),所以 dfs 一遍记录深度是有必要的……

    然后如果有一个点的两颗子树中都含有最小、最大深度,那么这种情况也是无解,可以令同时含有两种深度的子树 tag = 1。

    然后考虑最少交换次数,对于每一个节点的左右子树,三种情况需要交换:

     1. 左边全是小深度的,右边全是大深度的

     2. 左边全是小深度的,右边大小深度都有

     3. 左边大小深度都有,右边全是大深度的

    root->cnt = left_child->cnt + right_child->cnt + 本次是否需要交换(0 or 1)。

    所以代码判的挺多的……

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cctype>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 const int maxn = 200000 + 10;
    10 int n, in_deg[maxn], maxx, minn, ans, node_num;
    11 
    12 struct Node {
    13   int deep, cnt, tag, type;
    14   Node *lchild, *rchild;
    15 
    16   Node() { type = cnt = deep = 0, lchild = rchild = NULL; }
    17   ~Node() {};
    18 } node[maxn], *p_root;
    19 
    20 inline int read() {
    21   register char ch = 0; register int w = 0, x = 0;
    22   while( !isdigit(ch) ) w |= (ch == '-'), ch = getchar();
    23   while( isdigit(ch) ) x = (x * 10) + (ch ^ 48), ch = getchar();
    24   return w ? -x : x;
    25 }
    26 
    27 inline void Set_deep(Node *x) {
    28   if( x->lchild != NULL ) x->lchild->deep = x->deep + 1, Set_deep(x->lchild);
    29   if( x->rchild != NULL ) x->rchild->deep = x->deep + 1, Set_deep(x->rchild);
    30 }
    31 
    32 inline void Deep_fs(Node *x) {
    33   if( x->lchild == NULL && x->rchild == NULL ) return ;
    34   if( x->lchild != NULL ) Deep_fs(x->lchild);
    35   if( x->rchild != NULL ) Deep_fs(x->rchild);
    36   if( x->lchild->tag && x->rchild->tag ) ans = -1;
    37   if( x->lchild->type ^ x->rchild->type ) x->tag = 1;
    38   else if( x->lchild->tag | x->rchild->tag ) x->tag = 1;
    39   else if( x->lchild->deep != x->rchild->deep ) x->tag = 1;
    40   x->cnt = x->lchild->cnt + x->rchild->cnt;
    41   x->deep = max(x->lchild->deep, x->rchild->deep);
    42   if( x->lchild->tag ^ x->rchild->tag ) {
    43     if( x->lchild->tag && x->lchild->deep == x->rchild->deep ) ++x->cnt;
    44     if( x->rchild->tag && x->lchild->deep < x->rchild->deep ) ++x->cnt;
    45   } else if( x->lchild->deep < x->rchild->deep ) ++x->cnt;
    46 }
    47 
    48 int main(int argc, const char *argv[])
    49 {
    50   freopen("..\nanjolno.in", "r", stdin);
    51   freopen("..\nanjolno.out", "w", stdout);
    52 
    53   scanf("%d", &n), node_num = n, minn = 2e9;
    54   for(int l, r, i = 1; i <= n; ++i) {
    55     l = read(), r = read();
    56     if( l == -1 ) node[++node_num].type = 1, node[i].lchild = &node[node_num];
    57     else node[i].lchild = &node[l], ++in_deg[l];
    58     if( r == -1 ) node[++node_num].type = 1, node[i].rchild = &node[node_num];
    59     else node[i].rchild = &node[r], ++in_deg[r];
    60   }
    61   for(int i = 1; i <= n; ++i) if( in_deg[i] == 0 ) p_root = &node[i];
    62   p_root->deep = 1, Set_deep(p_root);
    63   for(int i = 1; i <= node_num; ++i) if( node[i].type ) {
    64     maxx = max(maxx, node[i].deep), minn = min(minn, node[i].deep);
    65   }
    66   if( maxx - minn > 1 ) puts("-1");
    67   else Deep_fs(p_root), printf("%d
    ", ans == -1 ? ans : p_root->cnt);
    68 
    69   fclose(stdin), fclose(stdout);
    70   return 0;
    71 }

     —— “从你慷慨的手里所付予的,我都接受。我别无所求。”
        “是了,是了,我懂得你,谦卑的乞丐,你是乞求一个人的一切所有。”

  • 相关阅读:
    web自动化测试---自动化脚本设置百度搜索每页显示条数
    web自动化测试---测试中其他一些常用操作
    web自动化测试---css方式定位页面元素
    web自动化测试---xpath方式定位页面元素
    linux系统 之 curl命令
    http协议
    php编程 之 php基础二
    shell编程 之 ssh远程连接
    php编程 之 php进阶练习
    php编程 之 php基础一
  • 原文地址:https://www.cnblogs.com/nanjoqin/p/10081893.html
Copyright © 2011-2022 走看看