Codeforces Round #428 (Div. 2) C. Journey (簡單搜尋)
阿新 • • 發佈:2020-11-02
-
題意:給你一顆樹(邊是無向的),從根節點向下走,統計走到每個子節點的概率,求所有葉子節點的深度乘上概率的和.
-
題解:每層子節點的概率等於上一層節點的概率乘\(1\)除以這層的子節點數,所以我們用\(dfs\)或者\(bfs\)都可以寫,其實就是個搜尋裸題,注意給出邊是無向的就好了.
-
程式碼:
1.dfs:
int n; int a,b; vector<int> v[N]; double ans; void dfs(int u,int fa,double p,int len){ if((int)v[u].size()==1 && u!=1){ ans+=p*len;len; return; } for(auto w:v[u]){ double p1; if(w==fa) continue; if(u==1) p1=p*(1.0/(double)(v[u].size())); else p1=p*(1.0/(double)(v[u].size()-1)); dfs(w,u,p1,len+1); } } int main() { //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); scanf("%d",&n); for(int i=1;i<n;++i){ scanf("%d %d",&a,&b); v[a].pb(b); v[b].pb(a); } dfs(1,-1,1.0,0); printf("%.6f\n",ans); return 0; }
2.bfs
struct misaka{ int node; int fa; double p; double len; }e; int n; int a,b; vector<int> v[N]; double ans; void bfs(){ queue<misaka> q; e.node=1;e.p=1.0;e.len=0.0;e.fa=-1; q.push(e); while(!q.empty()){ auto tmp=q.front(); q.pop(); int node=tmp.node; double p=tmp.p; double len=tmp.len; int fa=tmp.fa; if((int)v[node].size()==1 && node!=1){ ans+=p*len; } for(auto w:v[node]){ if(w==fa) continue; e.node=w; if(node==1) e.p=p*((double)1.0/(double)v[node].size()); else e.p=p*(1.0/(double)(v[node].size()-1)); e.len=len+1.0; e.fa=node; q.push(e); } } } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n; e.len=1.0; e.p=1.0; for(int i=1;i<n;++i){ cin>>a>>b; v[a].pb(b); v[b].pb(a); } bfs(); printf("%.6f\n",ans); return 0; }