This is not your task. Your task is: count the number of ways that minimizes the number of turns. Two ways are different if there exists some k such that in the k-th turn, the sender or receiver is different in the two ways.
Following are T test cases.
For each test case, the first line is number of people, n. Following are n-1 lines. Each line contains two numbers.
Sum of all n <= 1000000. OutputT lines, each line is answer to the corresponding test case. Since the answers may be very large, you should output them modulo 10 9+7. Sample Input
2 2 1 2 3 1 2 2 3Sample Output
2
6
題意:n個人構成一棵樹,每個人有一個獨特的信息,每輪最多有一個人把他攜帶的所有信息傳遞給和他相鄰的人,假如最多傳k輪所有人都能得到所有信息,問方案數有多少.
分析:考慮樹上的每條邊,可以看作有兩個方向,那麼每條邊最多傳入一次傳出一次,所以最少傳遞次數的上限爲2*(n-1),然後我們可以輕易的構造出來這種方案,只要選一個點爲根每次都先通過n-1把所有的信息都傳入給他,再通過n-1次將這個信息傳回所有點就可以了,然後我們考慮如何統計方案,考慮每個點都作爲一次匯點,假如傳入a的方案數爲f(a),那麼我們可以根據一一對應的法則證明從a傳出去的方案數也爲f(a),所以最後的答案就是sigma(f(a)^2),f(a)可以用樹形dp求出來,具體就是先隨便找一個點作爲根,然後dfs這棵樹並且求出來每個點的子樹符合拓撲序的所有方案數,然後再dfs一次求出以每個點爲匯點的方案數.
#include <bits/stdc++.h>
#define INF 1000111111
#define N 1000005
#define MOD 1000000007
using namespace std;
typedef long long ll;
int T,n,x,y;
ll ans,gc[N],igc[N],Ans[N],Down[N],Size[N];
vector<int> G[N];
void exgcd(ll a,ll b,ll &g,ll &x,ll &y)
{
if(!b) g=a,x=1,y=0;
else
{
exgcd(b,a%b,g,y,x);
y-=a/b*x;
}
}
ll inv(ll a,ll n)
{
ll d,x,y;
exgcd(a,n,d,x,y);
return d == 1 ? (x+n)%n : -1;
}
ll c(int x,int y)
{
return (gc[x]*igc[y] % MOD)*igc[x-y] % MOD;
}
void dfs1(int u,int fa)
{
Size[u] = 1,Down[u] = 1;
for(int v : G[u])
if(v != fa)
{
dfs1(v,u);
Size[u] += Size[v];
if(!Down[u]) Down[u] = Down[v];
else Down[u] = (Down[u]*Down[v] % MOD)*c(Size[u] - 1,Size[v]) % MOD;
}
}
void dfs2(int u,int fa)
{
if(u == 1) Ans[u] = Down[u];
else
{
ll res = (Ans[fa]*inv(Down[u],MOD) % MOD)*inv(c(n-1,Size[u]),MOD) % MOD;
Ans[u] = (c(n-1,Size[u]-1)*Down[u] % MOD)*res % MOD;
}
ans = (ans + Ans[u]*Ans[u] % MOD) % MOD;
for(int v : G[u])
if(v != fa) dfs2(v,u);
}
int main()
{
gc[0] = igc[0] = 1;
for(int i = 1;i < N;i++) gc[i] = (gc[i-1]*i) % MOD;
for(int i = 1;i < N;i++) igc[i] = inv(gc[i],MOD);
scanf("%d",&T);
while(T--)
{
ans = 0;
scanf("%d",&n);
for(int i = 1;i <= n;i++) G[i].clear();
for(int i = 1;i < n;i++)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs1(1,1);
dfs2(1,1);
cout<<ans<<endl;
}
}