Cf D. Nauuo and Circle

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;
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/10992709.html