题干:
Recently Kumiko learns to use containers in C++ standard template library.
She likes to use the std::vector very much. It is very convenient for her to do operations like an ordinary array. However, she is concerned about the random-access iterator use in the std::vector. She misunderstanding its meaning as that a vector will return an element with equal probability in this container when she access some element in it.
As a result, she failed to solve the following problem. Can you help her?
You are given a tree consisting of nn vertices, and 11 is the root of this tree. You are asked to calculate the height of it.
The height of a tree is defined as the maximum number of vertices on a path from the root to a leaf.
Kumiko's code is like the following pseudo code.
She calls this function dfs(1, 1), and outputs the maximum value of depth array.
Obviously, her answer is not necessarily correct. Now, she hopes you analyze the result of her code.
Specifically, you need to tell Kumiko the probability that her code outputs the correct result.
To avoid precision problem, you need to output the answer modulo 10^9 + 7109+7.
Input
The first line contains an integer nn - the number of vertices in the tree (2 \le n \le 10^6)(2≤n≤106).
Each of the next n - 1n−1 lines describes an edge of the tree. Edge ii is denoted by two integers u_iui and v_ivi, the indices of vertices it connects (1 \le u_i, v_i \le n, u_i \cancel= v_i)(1≤ui,vi≤n,ui=vi).
It is guaranteed that the given edges form a tree.
Output
Print one integer denotes the answer.
样例输入复制
5
1 2
1 3
3 4
3 5
样例输出复制
750000006
样例解释
Kumiko's code has \frac{3}{4}43 probability to output the correct answer.
题目大意:
给定一棵树,1号节点为根节点,定义了一下一棵树的深度。定义一个过程:从根节点出发,在节点x有son[x]次重复操作(son[x]为x节点的儿子节点个数),每次操作等概率进入某一儿子节点,同时记录最深深度dep。
现在调用一次dfs(1),求 dep==树的深度 的概率。
解题报告:
就是个n次独立重复试验,每一次的概率算出来,求个son[x]次方就行了。
注意判断叶子结点的时候别忘了特判根节点。、。。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 1e6 + 5;
const ll mod = 1e9 + 7;
ll qpow(ll a,ll b) {ll res = 1;while(b) {if(b&1) res = (res * a) % mod;b>>=1;a = (a*a)%mod;}return res;
}
int n,dep[MAX],ansd;
ll dp[MAX];
vector<int> vv[MAX];
void dfs(int cur,int fa,int deep) {dep[cur] = deep;ansd = max(ansd,deep);int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == fa) continue;dfs(v,cur,deep+1);}
}
void f(int cur,int fa) {if(vv[cur].size() == 1 && cur != 1) {if(dep[cur] == ansd) dp[cur] = 1;else dp[cur] = 0;return;}int up = vv[cur].size(),upp = vv[cur].size() - (cur!=1);ll tmp = 0; for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == fa) continue;f(v,cur);tmp += dp[v] *(qpow(upp,mod-2))%mod;tmp%=mod;}tmp = mod + 1 - tmp;//一次错误的tmp%=mod;tmp = qpow(tmp,upp)%mod; dp[cur] = mod+1-tmp;dp[cur]%=mod;
}
int main()
{cin>>n;if(n == 1) {printf("1\n");return 0;}for(int u,v,i = 1; i<=n-1; i++) {scanf("%d%d",&u,&v);vv[v].pb(u);vv[u].pb(v);}dfs(1,0,1);f(1,0);printf("%lld\n",dp[1]);return 0 ;
}