这次被虐残了,很好想的树上统计拓扑排序数,比赛的时候找儿子节点循环判断有一个很恶心的错误,一直到比赛结束都没找出来。
ACcode:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int NS=1000001;
const int MOD=1000000007;
struct node{
int num;
LL way;
}no[NS];
int n,top;
int head[NS],next[NS<<1],to[NS<<1];
LL ans,fac[NS],facm[NS];
void add(int u,int v)
{
to[top]=v;
next[top]=head[u];
head[u]=top++;
}
LL qpow(LL x,int y)
{
x%=MOD;
LL ret=1;
while (y>0)
{
if (y&1) ret*=x,ret%=MOD;
x*=x,x%=MOD;
y>>=1;
}
return ret;
}
LL cbn(int x,int y)
{
return (((fac[x]*facm[y])%MOD)*facm[x-y])%MOD;;
}
void dfs(int rt,int pre)
{
int cnt=0;
LL ret=1;
for (int i=head[rt];i!=-1;i=next[i])
{
int son=to[i];
if (son!=pre)
{
dfs(son,rt);
node tmp=no[son];
cnt+=tmp.num;
ret=(((ret*cbn(cnt,tmp.num))%MOD)*tmp.way)%MOD;
}
}
no[rt].num=cnt+1,no[rt].way=ret;
}
void dfs2(int rt,int pre)
{
if (pre>=0)
{
LL tmp=(no[pre].way*qpow(cbn(n-1,no[rt].num),MOD-2))%MOD;
no[rt].way=(tmp*cbn(n-1,n-no[rt].num))%MOD;
}
for (int i=head[rt];i!=-1;i=next[i])
if (to[i]!=pre)
dfs2(to[i],rt);
ans+=(no[rt].way*no[rt].way)%MOD;
}
int main()
{
int T;
facm[0]=fac[0]=1;
for (int i=1;i<NS;i++)
{
fac[i]=(fac[i-1]*i)%MOD;
facm[i]=qpow(fac[i],MOD-2);
}
for (scanf("%d",&T);T;T--)
{
ans=top=0;
memset(head,-1,sizeof(head));
scanf("%d",&n);
for (int i=1;i<n;i++)
{
int u,v;
scanf("%d %d",&u,&v);
add(u,v),add(v,u);
}
dfs(1,-1);
dfs2(1,-1);
ans%=MOD;
printf("%I64d\n",ans);
}
return 0;
}