题目链接
题目大意
给定一棵有
n
(
分析
- 不难得到,如果把1号结点作为根节点,每次只能往下一层结点走,则最后一定停在叶子结点。
因此,我们只需DFS这棵树,并且维护一个概率参量,初始设为1,当从某一结点向下一层结点出发时,概率参量 f /当前结点的儿子个数,直到遍历到叶子结点时,
ans+=depth⋅f 一个结点的儿子数=它的度数-1
代码
#include <bits/stdc++.h>
using namespace std;
const double pi=4*atan(1.0);
const int MAXN=100010;
const int MAXM=2*MAXN;
struct Edge
{
int to,next;
}e[MAXM];
int head[MAXN],ind[MAXN],edgenum,n;
double ans;
void Add_Edge(int u,int v)
{
ind[v]++;///记录结点度数
e[++edgenum].to=v;
e[edgenum].next=head[u];
head[u]=edgenum;
}
void dfs(int u,int p,int d,double f)///u为当前访问结点,P为父亲结点,d为深度,f为概率系数
{
for (int t=head[u];t!=-1;t=e[t].next)
{
int v=e[t].to;
if (v==p) continue;
dfs(v,u,d+1,f/ind[u]);
}
/*此处结点以无路可走*/
if (ind[u]==0)///只会停在叶子节点
ans+=f*d;
}
int main()
{
int i,u,v;
scanf("%d",&n);
edgenum=0;
memset(head,-1,sizeof(head));
memset(ind,0,sizeof(ind));
for (i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
Add_Edge(u,v);
Add_Edge(v,u);
}
for (i=2;i<=n;i++)
ind[i]--;///减去来自父亲结点的度数
ans=0;
dfs(1,0,0,1);
printf("%.8lf\n",ans);
return 0;
}