APIO2007 风铃

Posted CaptainLi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了APIO2007 风铃相关的知识,希望对你有一定的参考价值。

传送门

这道题好巧妙啊……

首先根据题目大意可以知道如果有风铃的深度差值大于1的话那么肯定是不合法的,风铃的深度就可以被看成高的和低的(雾)。

然后,我们要进行交换,但是交换其实并不会改变一个节点所在的子树,也就是说,你不可能把某一个子树从树里面分裂出来再放回去,所以,如果一个节点的左右两棵子树内全都又有高风铃,又有低风铃,那么肯定是无法交换完成的。

否则的话,一共有三种情况需要我们交换:

1.左边全都是深度低的,右边全都是深度高的

2.左边全是深度低的,右边深度高低的都有

3.左边深度高低的都有,右边全是深度高的。

因为我们是递归返回的时候从下向上进行交换,所以我们可以保证在某一层进行交换的时候,子树一定是有序的,所以以上三种情况我们每次交换只要交换一次既满足情况。同时我们可以返回的时候特判不合法情况,同时返回下一层情况。我的做法是用0,1,2来表示上面三种情况,直接返回即可。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar(‘
‘)

using namespace std;
typedef long long ll;
const int M = 100005;
const int INF = 1000000009;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < 0 || ch > 9)
    {
    if(ch == -) op = -1;
    ch = getchar();
    }
    while(ch >= 0 && ch <= 9)
    {
    ans *= 10;
    ans += ch - 0;
    ch = getchar();
    }
    return ans * op;
}

struct node
{
    int lc,rc;
}t[M];

int n,ans,maxn = 0,minn = 100000000;
bool flag;

void dfs(int x,int depth)
{
    if(x == -1)
    {
    minn = min(minn,depth),maxn = max(maxn,depth);
    return;
    }
    dfs(t[x].lc,depth+1),dfs(t[x].rc,depth+1);
}

int solve(int x,int depth)
{
    if(x == -1) return (depth == minn) ? 0 : 1;
    int a = solve(t[x].lc,depth+1),b = solve(t[x].rc,depth+1);
    if((a == 0 && b == 1) || (a == 2 && b == 1) || (a == 0 && b == 2)) ans++;
    if(a == 2 || b == 2)
    {
    if(a == 2 && b == 2) flag = 1;
    return 2;
    }
    if(!a && !b) return 0;
    if(a + b == 1) return 2;
    if(a == 1 && b == 1) return 1;
}

int main()
{
    n = read();
    rep(i,1,n) t[i].lc = read(),t[i].rc = read();
    dfs(1,0);
    if(maxn - minn > 1) printf("-1
");
    else if(maxn == minn) printf("0
");
    else
    {
    solve(1,0);
    flag ? printf("-1
") : printf("%d
",ans);
    }
    return 0;
}

 

以上是关于APIO2007 风铃的主要内容,如果未能解决你的问题,请参考以下文章

P3621 [APIO2007]风铃

[APIO/ctsc2007]

[CTSC2007][APIO2007]数据备份Backup

[APIO2007]动物园 --- 状压DP

P3620 [APIO/CTSC 2007]数据备份

P3620 [APIO/CTSC 2007] 数据备份