https://codeforces.com/contest/1173/problem/D
题意:
给出你一个包含 n 个点的树,这 n 个点编号为 1~n;
给出一个圆,圆上放置 n 个位置,第 i 个位置对应树中的某个节点,并且不重复;
求在圆上还原这棵树后,使得边不相交的总方案数;
学习出:https://www.cnblogs.com/violet-acmer/p/10991346.html
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353; const int M=2e5+5; struct node{ int nextt,v; }e[M<<1]; vector<int>son[M]; int head[M],n,tot; ll fac[M],dp[M]; void addedge(int u,int v){ e[tot].v=v; e[tot].nextt=head[u]; head[u]=tot++; } void dfs(int u,int f){ for(int i=head[u];~i;i=e[i].nextt){ int v=e[i].v; if(v==f) continue; son[u].push_back(v); dfs(v,u); } int flag=0; if(u!=1) flag=1; int k=son[u].size()+flag; dp[u]=fac[k]; for(int i=0;i<son[u].size();i++){ dp[u]=dp[u]*dp[son[u][i]]%mod; } } ll solve(){ dfs(1,1); return dp[1]*n%mod; } int main(){ scanf("%d",&n); fac[0]=1; for(int i=1;i<=n;i++) fac[i]=(i*fac[i-1])%mod; memset(head,-1,sizeof(head)); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } printf("%I64d",solve()); return 0; }