標籤:int || void col ++ tin continue oid dash
感覺對期望也一無所知……(;′⌒`)╮(╯﹏╰)╭
一直在考慮怎麼dp,最後看了題解——竟然是這樣的???【震驚】但是看了題解之後,覺得確實很有道理……
我們可以考慮最後答案的組成,可以分開計算不同的點對於答案的貢獻(期望具有線性性)。我們可以把這個染色的過程看做每一個節點均需要被染色,但只有第一個被染色的節點會消耗1點代價。這樣我們就可以分別分析每個點對於答案產生貢獻的機率,答案即為機率之和。而一個點會對答案產生影響的機率是多少?實際上這隻與它到根的鏈上的節點是相關的,因為只要在染色它的祖先節點之前染色它,它就會對答案產生為1的貢獻。
那麼當它和它的祖先均未被染色時,顯然有選擇任意節點的機率相等,顯然有選擇它的機率為 \(\frac{1}{dep[u]}\)(如果選擇了其他節點,則該節點無法再產生貢獻)。於是……這題就做完了。強啊!%%%
#include <bits/stdc++.h>using namespace std;#define maxn 200000#define db doubleint n, dep[maxn];db ans;int read(){ int x = 0, k = 1; char c; c = getchar(); while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) k = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar(); return x * k;}struct edge{ int cnp, to[maxn], last[maxn], head[maxn]; edge() { cnp = 2; } void add(int u, int v) { to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++; to[cnp] = u, last[cnp] = head[v], head[v] = cnp ++; }}E1;void dfs(int u, int fa){ for(int i = E1.head[u]; i; i = E1.last[i]) { int v = E1.to[i]; if(v == fa) continue; dep[v] = dep[u] + 1; dfs(v, u); }}int main(){ n = read(); for(int i = 1; i < n; i ++) { int u = read(), v = read(); E1.add(u, v); } dep[1] = 1; dfs(1, 0); for(int i = 1; i <= n; i ++) ans += (1.0 / (db) dep[i]); printf("%.10lf\n", ans); return 0;}
【題解】CF#172(Div. 1) C.Game on Tree