原题: http://codeforces.com/contest/1173/problem/D
题意:
给出一棵树的边,现在你将所有点放在一个圆上,使所有边不能交叉,问方案数。
解析:
显然,因为没有环,所以只需要看现在有多少条边即可。
例如我现在连了2条边,那么我可以往三块区域连边,所以答案乘3。
如果当前没有连边,那么我可以往所有段内放这条边(开始时段为1,连了一条边后变成两段了),所以答案乘上段数。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=200009;
const LL mod=998244353;
LL ct[maxn];
bool vis[maxn];
int x[maxn],y[maxn];
vector<int>V[maxn];
vector<int>::iterator it;
LL seg;
LL ans=1;
void dfs(int p){
if(vis[p])return;
vis[p]=1;
for(int i=0;i<V[p].size();i++){
int to=V[p][i];
if(vis[to])continue;
ct[p]++;
ct[to]++;
ans=ans*ct[p]%mod;
seg++;
dfs(to);
}
}
int main(){
int n;scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&x[i],&y[i]);
V[x[i]].push_back(y[i]);
V[y[i]].push_back(x[i]);
}
seg=1;
for(int i=1;i<=n;i++){
if(ct[i]==0)ans=ans*seg%mod;
dfs(i);
}
printf("%lld\n",ans*(LL)n%mod);
}