BZOJ1149 [CTSC2007]风玲
Description
Input
Output
输出仅包含一个整数。表示最少需要多少次交换能使风铃满足Ike的条件。如果不可能满足,输出-1。
Sample Input
6
2 3
-1 4
5 6
-1 -1
-1 -1
-1 -1
2 3
-1 4
5 6
-1 -1
-1 -1
-1 -1
Sample Output
2
题解
首先,算出每个结点的maxdep和mindep,即这个子树里叶结点的最大、最小深度。
如果maxdep[1]-mindep[1]>1,无解。
看某个结点,如果它的叶结点深度统一,直接忽略;如果它的两个子结点的子树里深度都不是统一的,无解;否则,如果maxdep[l]<=mindep[r],就要交换。反之则不交换。
代码:
#include <algorithm> #include <cstdio> const int N = 100050; int s[N][2], mindep[N], maxdep[N]; int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d%d", &s[i][0], &s[i][1]); s[i][0] = std::max(s[i][0], 0); s[i][1] = std::max(s[i][1], 0); } for (int i = n; i; --i) { int l = s[i][0], r = s[i][1]; mindep[i] = std::min(mindep[l], mindep[r]) + 1; maxdep[i] = std::max(maxdep[l], maxdep[r]) + 1; } if (maxdep[1] - mindep[1] > 1) return puts("-1") & 0; int ans = 0; for (int o = n; o; --o) { if (mindep[o] == maxdep[o]) continue; int l = s[o][0], r = s[o][1]; if (maxdep[l] <= mindep[r]) ++ans; if (mindep[r] != maxdep[r] && mindep[l] != maxdep[l]) return puts("-1") & 0; } return printf("%d\n", ans) & 0; }