【bzoj1149】【ctsc2007】【风铃】【dp】

Description

   

Input

Output

输出仅包含一个整数。表示最少需要多少次交换能使风铃满足Ike的条件。如果不可能满足,输出-1。

Sample Input

6
2 3
-1 4
5 6
-1 -1
-1 -1
-1 -1

Sample Output

2
题解:这个题关键是看懂题。
首先要先判断是否可以满足。一遍dfs即可。统计一下最大深度和最小深度(算-1)。如果差值超过2就无解。
然后dp一下即可。
在dp的过程中如果发现有一棵子树的左右子树中中都既有最大深度又有最小深度。
那么显然是无解。
其他的话分情况讨论一下即可。
代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#define N 100010
using namespace std;
int n,maxx,minn(9999999),l[N],r[N],ans;
void dfs(int x,int cnt)
{
    if (x==-1){maxx=max(maxx,cnt);minn=min(minn,cnt);return;}
    dfs(l[x],cnt+1);
    dfs(r[x],cnt+1);
}
int slove(int x,int cnt)
{
   int a,b;
   if (x==-1)
   { 
      if (cnt==minn) return 1;else return 2;
   }
   a=slove(l[x],cnt+1);
   b=slove(r[x],cnt+1);
   if (a==1&&b==2||a==1&&b==3||a==3&&b==2) ans+=1;
   if (a==3&&b==3){printf("-1\n");exit(0);}
   return a|b;
}
void pre()
{
    dfs(1,0);
    if (maxx-minn>=2){printf("-1\n");exit(0);}
    if (maxx==minn){printf("0\n");exit(0);}
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&l[i],&r[i]);
    pre();
    slove(1,0);
    printf("%d",ans);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值