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

时间: 2024-11-10 admin IT培训

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

【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);
}