rt,思路和题解都不一样,赛场想的,怀疑自己的证明是假的。
考虑菊花,其实就是边组成的完全图,树就是若干完全图,然后完全图直间共用点,考虑到如果初始节点定了,这些完全图像菊花一样左端点就定了(因为从初始到这个完全图上任意节点,第一个节点可以确定),所以就是每个完全图不合法方案的乘积,考虑 dfs 序中进行,每个完全图初始节点改一次,贡献改一次,这样可以线性扫。
感觉没啥问题,但是代码只能过 k=1 和菊花图和链。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mod 1000000007ll
struct bi{
int u,v;
}ss[1000009],zs[1000009];
int jc[1000009];
int ksm(int a,int b){
int ans;
ans=1;
while(b){
if(b&1){
ans*=a;
ans%=mod;
}
a*=a;
a%=mod;
b>>=1;
}
return ans;
}
int dfn[1000009];
int nfd[1000009];
struct st{
int v,ne;
}sd[1000009];
int h[1000009];
int inn;
void add(int u,int v){
sd[++inn].v=v;
sd[inn].ne=h[u];
h[u]=inn;
}
int de,ans;
int ds[1000009];
int rr[1000009];
int bb[1000009];
void dfs(int t,int fa){
dfn[++inn]=t;
nfd[t]=inn;
int zz;
zz=inn;
for(int i=h[t];i;i=sd[i].ne){
if(sd[i].v!=fa)
dfs(sd[i].v,t);
}
rr[zz]=inn;
}
bool cmp(int x,int y){
return ss[x].u==ss[y].u?ss[x].v<ss[y].v:ss[x].u<ss[y].u;
}
bool cmp2(bi a1,bi a2){
return a1.v==a2.v?a1.u<a2.u:a1.v<a2.v;
}
int bj[1000009];
vector<int> g[1000009];
int nn[1000009];
int ggg;int n,k;
int xa,xb;
void ddfs(int t,int &rw,int fa){
if(ss[bb[rw]].v==t){
ans+=ggg-de;
ans+=mod;
ans%=mod;
rw++;
}
if(ss[bb[rw]].v<t||ss[bb[rw]].v>rr[t]||rw>k){
return;
}
for(int i=1;i<=nn[t];i++){
if(ss[bb[rw]].v>=g[t][i]&&ss[bb[rw]].v<=rr[g[t][i]]&&g[t][i]!=fa){
if(t!=xa||g[t][i]!=xb){
bj[t]++;
if(bj[t]==1){
de*=ksm(ds[t]-1,mod-2);
de%=mod;
}else{
de*=ksm(bj[t]-1,mod-2);
de%=mod;
de*=bj[t];
de%=mod;
}
}
ddfs(g[t][i],rw,t);
}
}
}
int ssd[1000009];
void _main(){
inn=0;
cin>>n>>k;
for(int i=1;i<=n;i++){
h[i]=dfn[i]=ds[i]=ssd[i]=0;
g[i].push_back(0);
nn[i]=0;
nfd[i]=0;
ggg=0;
bj[i]=0;
bb[i]=rr[i]=0;
}
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
ss[i]={u,v};
add(u,v),add(v,u);
ssd[u]++;
ssd[v]++;
}
for(int i=1;i<=k;i++){
cin>>bb[i];
}
inn=0;
if(ssd[ss[bb[k]].u]!=1)
dfs(ss[bb[k]].u,0);
else
dfs(ss[bb[k]].v,0);
k--;
for(int i=1;i<n;i++){
ss[i].u=nfd[ss[i].u];
ss[i].v=nfd[ss[i].v];
if(ss[i].u>ss[i].v){
swap(ss[i].u,ss[i].v);
}
ds[ss[i].u]++,ds[ss[i].v]++;
}
for(int i=1;i<n;i++){
zs[i]=ss[i];
}
sort(zs+1,zs+n,cmp2);
for(int i=1;i<n;i++){
int x,y;
x=zs[i].u,y=zs[i].v;
if(x>y){
swap(x,y);
}
g[x].push_back(0);
g[x][++nn[x]]=y;
}
sort(bb+1,bb+1+k,cmp);
ans=1;
for(int i=1;i<=n;i++){
ans*=jc[ds[i]-1];
ans%=mod;
}
ggg=ans;
de=ans;
for(int i=1;i<=n;i++){
bj[i]=0;
}
int rw;
rw=1;
xa=ss[bb[k+1]].u,xb=ss[bb[k+1]].v;
ddfs(1,rw,0);
cout<<ans<<endl;
}
signed main(){
std::ios::sync_with_stdio(0);
jc[0]=1;
for(int i=1;i<=1000000;i++){
jc[i]=jc[i-1]*i%mod;
}
int c,t;
cin>>c>>t;
while(t--){
_main();
}
return 0;
}