題目鏈結
題目鏈結是洛谷翻譯過的。
題意:給你一棵樹,邊權都是1,每乙個點有乙個是起點的概率和乙個是終點的概率,你將以起點為根,開始在樹上隨機dfs,直到走到終點。求dfs從起點到終點的期望長度。n<=10w
題解:我們考慮一條確定路徑從s到t的期望步數的計算方法。我們發現,這個答案根據期望的線性性,我們可以拆成在這條路徑上每個點到下乙個點的期望步數之和。那麼我們考慮如何求乙個點到下乙個點的期望步數。
乙個點走到下乙個點的過程中,可能先走遍其中的某幾個子樹,然後再走到想要走的方向。我們假設當前點的度數為x
xx,那麼從當前點走到每乙個點的概率都是1
x\frac
x1,而走進乙個子樹之後就會把整個子樹全部遍歷,由於去和回經過每條邊兩次,所以走到每個非目標點y
yy的貢獻都是1x∗
size
[y]∗
2\frac*size[y]*2
x1∗si
ze[y
]∗2。由於我們隨機選取當前點能到達的沒有訪問過的點走,所以對於任意當前點能到達兩個點a
aa和b
bb,在隨機選擇點去走的情況下a
aa在b
bb前面和b
bb在a
aa前面的概率都是1
2\frac
21,於是剛才的貢獻應該再乘1
2\frac
21,那麼乙個非兩點在子樹的貢獻就是子樹大小乘當前點的度數。
對於這個題的做法,我們是列舉每乙個點作為終點時對答案的貢獻,考慮起點在每個點為根的子樹內的概率,我們其實由剛才的式子化簡可以得到,在某個子樹內的點的貢獻就是子樹大小,於是根據期望=概率*權值,以及期望的線性性,我們遍歷每個點能到達的點以及他們的子樹大小,然後乘概率和就是這個點的貢獻,最後答案是對每個點的答案求和。
**:
#include
using
namespace std;
int n,hed[
100010
],cnt,sz[
100010
],fa[
100010];
double ru[
100010
],chu[
100010
],sru,schu,ans;
struct node
a[200010];
inline
void
add(
int from,
int to)
inline
void
dfs(
int x)
}int
main()
for(
int i=
1;i<=n;
++i)
for(
int i=
1;i<=n;
++i)
ru[i]
/=sru;
dfs(1)
;for
(int x=
1;x<=n;
++x)
}printf
("%.12lf\n"
,ans)
;return0;
}
CF123E Maze(期望dp,樹形dp,式子)
題目鏈結 題目大意 給你一棵樹,邊權都是1,每乙個點有乙個是起點的概率和乙個是終點的概率,你將以起點為根,開始在樹上隨機dfs,每到乙個點,就會將他的所有兒子隨機打亂成序列,然後按照那個隨機順序走完,直到走到終點。求dfs從起點到終點的期望長度。其實一開始看到這個題,還是有點懵逼的啊 根據期望的線性...