樹上兩點期望距離

2022-09-12 10:42:18 字數 1879 閱讀 5219

求樹上兩點之間的期望距離。

設d[i]為i節點的度數。

fa[i]為i節點的父親。

我們對於兩種不同的走法分別考慮。

part1:兒子到父親

設此時期望步數為f[i]。

顯然,只會有兩種情況:

1.直接一步走到父親。

2.先走到自己的兒子,再走回自己,再走到父親。

對於情況1.概率為$ \frac$ ,步數為1,期望為 $ \frac$。

對於情況2.分步考慮:

\(1^\) :走到兒子,發生概率為 $ \frac$ ,步數為1,期望為$ \frac$

\(2^\) :兒子走到自己,期望為 $ \sum\limits_\frac $

\(3^\) :自己走到父親,期望為 $ \frac$

綜上,我們有:

\[f[i]=\frac}

\]移項化簡之後我們得到:

\[f[i]=d[i]+\sum\limits_f[j]

\]part2:父親到兒子。

設此時期望步數為g[i]。

那麼,我們有三種情況

1.直接跳到指定的兒子。

2.跳到父親的父親,再回到該點,再到達指定兒子。

3.跳到另乙個兒子,再跳回來,再到達指定兒子。

還是像f陣列一樣討論即可。

\[g[i] = \frac}

\]化簡後:

\[g[i]=g[fa[i]]+d[fa[i]]+\sum\limits_f[son]

\]好了,兩種情況都考慮完之後,就可以算距離了。

距離計算

對於給定的u--->v的路徑,我們可以拆成兩條:\(u \to lca\); \(lca\to v\)。

其中對於第一條路徑,肯定都是向上走,另一條則是向下的。

所以:\[ans=\sum\limits_f[i]+\sum\limits_g[i]-f[lca]-g[lca]

\]記乙個樹上字首和即可。

#include using namespace std;

#define debug(...) fprintf(stderr, __va_args__)

#define mp make_pair

#define fst first

#define snd second

templateinline bool chkmin(t &a, const t &b)

templateinline bool chkmax(t &a, const t &b)

inline int read()

typedef long long ll;

typedef pairpii;

const int maxn = 5e4 + 10;

int fa[maxn][17], dep[maxn];

ll up[maxn], down[maxn];

vector g[maxn];

void clean(int n)

void dfsu(int now, int pa)

}void dfsd(int now, int pa, int ppa)

}void dfs(int now,int pa)

}int lca(int u,int v)

void solve()

dfsu(1, 0);

dfsd(1, 0, 0);

dfs(1, 0);

int q = read();

for (int i = 1; i <= q; ++i)

printf("%lld.0000\n",ans);

} clean(n);

}int main()

return 0;

}

樹上兩點期望距離

對於樹上的節點 i 設 d i 為 i 的度數,fa 為 i 的父親,sum limits j 為 i 的兒子。假設邊權均為 1 分別考慮兒子到父親 父親到兒子的期望。設 f i 表示兒子 i 到父親的期望距離。可以分為 2 種情況 直接到父親。概率為 dfrac 步數為 1 期望為 dfrac 先...

1102 兩點距離

兩點距離 time limit 1000ms memory limit 65536k total submit 495 accepted 227 description 輸入4個絕對值在1000000以內的整數 x1,y1,x2,y2,輸出平面座標系中點 x1,y1 到點 x2,y2 之間的距離 保...

1279 兩點距離

1279 兩點距離 description 輸入4個絕對值在1000000以內的整數x1,y1,x2,y2輸出平面座標系中點 x1,y1 到點 x2,y2 之間的距離 保留三位小數 input 輸入4個整數x1,y1,x2,y2。output 輸出平面座標系中點 x1,y1 到點 x2,y2 之間的...