我們知道一棵有根樹可以進行深度優先遍歷(dfs)以及廣度優先遍歷(bfs)來生成這棵樹的 dfs 序以及 bfs 序。兩棵不同的樹的 dfs 序有可能相同,並且它們的 bfs 序也有可能相同,例如下面兩棵樹的 dfs 序都是 1 2 4 5 3,bfs 序都是 1 2 3 4 5。
現給定乙個 dfs 序和 bfs 序,我們想要知道,符合條件的有根樹中,樹的高度的平均值。即,假如共有
k 棵不同的有根樹具有這組 dfs 序和 bfs 序,且他們的高度分別是 h1
,h2,
…,hk
,那麼請你輸出:h1
+h2+
⋯+hk
k 第一行包含
1 個正整數
n,表示樹的節點個數。
第二行包含
n 個正整數,是乙個 1∼
n的排列,表示樹的 dfs 序。
第三行包含
n 個正整數,是乙個 1∼
n的排列,表示樹的 bfs 序。
輸入保證至少存在一棵樹符合給定的兩個序列。
僅包含
1 個實數,四捨五入保留恰好三位小數,表示樹高的平均值。
input
5output1 2 4 5 3
1 2 3 4 5
3.500如果輸出檔案的答案與標準輸出的差不超過 10−
3,則將獲得該測試點上的分數,否則不得分。
20% 的測試資料,滿足:n≤
10 ;
40% 的測試資料,滿足:n≤
100 ;
85% 的測試資料,滿足:n≤
2000
;100% 的測試資料,滿足:2≤
n≤200000
。時間限制:1s
空間限制:
256mb
樹的高度:一棵有根樹如果只包含乙個根節點,那麼它的高度為
1 。否則,它的高度為根節點的所有子樹的高度的最大值加 1。
對於樹中任意的三個節點 a,
b,c ,如果 a,
b 都是
c 的兒子,則 a,
b在 bfs 序中和 dfs 序中的相對前後位置是一致的,即要麼
a 都在
b的前方,要麼
a 都在
b的後方。
我們將bfs序列改為1…
n ,對應的也修改dfs序的標號。 令p
os[i
] 表示bf
s 序為
i 的節點在df
s序中的位置。
然後我們要做的就會要對bf
s 序分層。
每一種分層對應幾種滿足dfs序的方案呢?
這相當於問子節點到父節點有幾種連法。所以一種劃分只對應一棵樹。在兩種不同連法中,父1,父2,子 的相對順序不同,所以只有一種符合dfs序。
然後我們來看看應該應該怎麼分層。
首先,考慮一下同一層的點應該滿足的條件
令這一層的節點為[l
,r]
pos[i
]s[i+
1]i∈
[l,r
) ,這個性質很顯然,因為dfs和bfs都是遍歷乙個節點的領接邊的順序是一樣的。
1號節點必須單獨成層。
我們再來看看df
s 序的性質,假設df
s 序為d[
1]…d
[n]
令x[i
] 表示
i 和i+
1節點之間的分層情況。
特別地,x[
1]=1
顯然de
p[i+
1]≤d
ep[i
] ,但是i+
1 比
i 在深度優先遍歷中先遍歷到,只能說明i+
1和i 不是同一層的。x[
i]=1
那麼x[d
[i]]
+x[d
[i]+
1]+⋯
+x[d
[i+1
]−1]
<=
1 ,也就是d[
i]和d[i
+1] 之間最多分一層,對應了df
s 序的性質,de
p[d[
i+1]
]−de
p[d[
i]]<=
1 ,如果x[
d[i]
],x[
d[i]
+1]⋯
x[d[
i+1]
−1] 直接有任何乙個地方因為上乙個條件分層了,那麼這裡就不能分了。
否則這一段內可以分一層,可以不分層,概率相等,所以我們令x[
d[i]
]=0.5 ,代表這一段的分層情況。
最後求答案就很簡單了an
s=∑i
=1n−
1x[i
]
#include
#include
using
namespace
std;
#define maxn 200000
int a[maxn+10],b[maxn+10],d[maxn+10],pos[maxn+10],g[maxn+10],sta[maxn+10],tp,n;
double x[maxn+10],s[maxn+10],ans=1;
void read(int &x)
}void read()
for(i=1;i<=n;i++)
}void solve()
for(i=1;iif(d[i]1])
}for(i=1;i<=n;i++)
g[i]+=g[i-1];
for(i=1;i<=tp;i++)
if(!g[sta[i]])
x[sta[i]]=0.5;
for(i=1;i<=n;i++)
ans+=x[i];
}int main()
bfs和dfs的特點
一 深度優先搜尋 dfs 的特點是 1 深度優先搜尋法有遞迴以及非遞迴兩種設計方法。一般的,當搜尋深度較小 問題遞迴方式比較明顯時,用遞迴方法設計好,它可以使得程式結構更簡捷易懂。當資料量較大時,由於系統堆疊容量的限制,遞迴容易產生溢位,用非遞迴方法設計比較好。2 深度優先搜尋方法有廣義和狹義兩種理...
dfs和bfs的應用
dfs 能找到可行的路徑,所需時間長,需要標記位置 bfs 能找到最短的路徑,所需空間長,需要出入佇列 兩個搜尋的相同點是都利用了二維陣列的圖,有的時候都用了標記方法。但是dfs,我覺得沒什麼變化,就這樣了。但是bfs,1.可以用stl的queue,但是,沒辦法對付路徑記錄。2.可以用自己寫的結構體...
dfs和bfs的總結
dfs dfs演算法是乙個對連通圖進行遍歷的演算法。它的思想是從乙個被選定的點出發一條路走到底,如果得不到目的解,那就返回到上乙個節點,然後換一條路繼續走到底,直到找到目的解返回或者全部遍歷完返回乙個事先定好的值。dfs一般借用遞迴完成整個演算法的構造。dfs演算法的一般框架經我總結大致為下 int...