1. 程式人生 > >BZOJ1149:[CTSC/APIO2007]風鈴——題解

BZOJ1149:[CTSC/APIO2007]風鈴——題解

while -s tdi lock () getchar getc har span

https://www.lydsy.com/JudgeOnline/problem.php?id=1149

https://www.luogu.org/problemnew/show/P3621

技術分享圖片

sb貪心,然而跪了兩次才A……一次還是我自己出的樣例都沒過結果就交了……

dep[i]表示i子樹最深深度,up[i]表示i子樹是否有不同層的風鈴。

那麽深搜一下就行了,判斷方法看我代碼吧……懶得講了。

#include<cmath>
#include<queue>
#include
<vector> #include<cstdio> #include<cctype> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch==-;ch=getchar();}
while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } int n,ch[N][2],dep[N],up[N]; bool ok; void dfs1(int u){ int l=ch[u][0],r=ch[u][1]; if(!l)dep[u]=1; else{ dfs1(l);dep[u]=dep[l]+1; } int tmp; if(!r)tmp=1; else{ dfs1(r);tmp
=dep[r]+1; } if(abs(tmp-dep[u])>1)ok=1; else if(abs(tmp-dep[u])==1)up[u]=1; dep[u]=max(dep[u],tmp); up[u]|=up[ch[u][0]];up[u]|=up[ch[u][1]]; } int ans; void dfs2(int u){ if(!u)return; if(dep[ch[u][0]]<dep[ch[u][1]]){ swap(ch[u][0],ch[u][1]);ans++; } else if(dep[ch[u][0]]==dep[ch[u][1]]){ if(up[ch[u][0]]&&up[ch[u][1]])ok=1; else if(up[ch[u][0]]){ swap(ch[u][0],ch[u][1]);ans++; } } dfs2(ch[u][0]);dfs2(ch[u][1]); } int main(){ n=read(); for(int i=1;i<=n;i++){ ch[i][0]=read(),ch[i][1]=read(); if(ch[i][0]==-1)ch[i][0]=0; if(ch[i][1]==-1)ch[i][1]=0; } dep[0]=0; dfs1(1); dfs2(1); printf("%d\n",ok?-1:ans); return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ1149:[CTSC/APIO2007]風鈴——題解