ノードラベル(最小限の影響)がエミュレートされる(順番)|明らかに少ない数を満たすため、より深いノードの深さの最適解が存在しなければならない、それは、(それ自身標識されているサブツリーノードの外側に加えて、リーフノード)大嗜好に小さいからです最適なソリューションを提供します。
したがって、成形圧力リーフノードを考慮すると、転送処理は、リーフノード番号として次のノードに直接または間接的に決定された電流cの計算量を必要とします。複雑Oは((N + n)が2 ^ 20)許容できません
しかし、リーフノード20を考慮して、しかし、仮想ツリー(リーフノードは臨界点である)が、加算点40は、このようにして配列のようなツリーを使用して加速しました。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+3;
const int P=1e9+7;
int n,m,cnt;
int fa[41],val[41],siz[41],id[21];
vector<int> G[N];
int f[1<<20],t[41];
double g[1<<20];
void dfs(int x,int p,int d,int w) {
if(G[x].size()==2) {
for(int y:G[x]) if(y!=p) dfs(y,x,d,w+(d!=0));
return;
}
cnt++; fa[cnt]=d;
siz[cnt]=val[cnt]=w; d=cnt;
if(G[x].size()==1) id[m++]=d;
for(int y:G[x]) if(y!=p) dfs(y,x,d,1);
siz[fa[d]]+=siz[d];
}
int main() {
scanf("%d",&n);
for(int x,y,i=n; --i; ) {
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
G[1].push_back(0);
dfs(1,0,0,1);
memset(f,-0x3f,sizeof f);
memset(g,-0x7f,sizeof g);
f[0]=1; g[0]=1;
for(int s=0; s<(1<<m); ++s) {
int now=0;
memset(t,0,sizeof t);
for(int x=0; x<m; ++x) if(!((s>>x)&1)) t[id[x]]=-1;
for(int x=cnt; x; --x) {
if(t[x]==siz[x]-val[x]) now+=val[x],t[x]+=val[x];
t[fa[x]]+=t[x];
}
for(int x=0; x<m; ++x) if(!((s>>x)&1)) {
if(g[s|(1<<x)]<g[s]*(now+1)) {
g[s|(1<<x)]=g[s]*(now+1);
f[s|(1<<x)]=1LL*f[s]*(now+1)%P;
}
}
}
printf("%d\n",f[(1<<m)-1]);
return 0;
}