BZOJ1149 - [APIO2007][CTSC2007]风玲Mobiles

2016/12/31

题目描述

代码

通过最大最小深度来搜,摆放反了的时候就旋转一下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <limits>
#define nlimit numeric_limits
using namespace std;
const int PSIZ = 1E5 + 1E3;
int N;
int L[PSIZ], R[PSIZ];

int maxd, mind;
void dfs(int cur, int dep) {
    if(cur == -1) { maxd = max(maxd, dep); mind = min(mind, dep); return; }
    dfs(L[cur], dep+1); dfs(R[cur], dep+1);
}

int ans = 0;
#define pack(a, b) ((a << 4) + b)
int solve(int cur, int dep) {
    int a, b;
    if(cur == -1) return (dep!=mind) + 1;
    a = solve(L[cur], dep+1);
    b = solve(R[cur], dep+1);
    switch(pack(a, b)) {
    case pack(1, 2):
    case pack(1, 3):
    case pack(3, 2): ans += 1; break;
    case pack(3, 3): printf("-1\n"); exit(0); break;
    }

    return a|b;
}

void work() {
    maxd = nlimit<int>::min();
    mind = nlimit<int>::max();
    dfs(1, 0);

    if(maxd - mind >= 2) { printf("-1\n"); exit(0); }
    if(maxd == mind) { printf("0\n"); exit(0); }

    solve(1, 0);
}

int main() {
    scanf("%d", &N);

    for(int i=1;i<=N;i++) {
        scanf("%d %d", &L[i], &R[i]);
    }

    work();

    printf("%d\n", ans);
}