2021icpc上海站G

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int maxn=1e5+5;
vector<int>v[maxn];
int n,x,y;
ll vis[maxn],sum=1,a[maxn],size[maxn];
//size代表当前节点下可用的边数 ,vis代表这个节点上的边是否被占用 
void dfs(int now,int fa){
	size[now]=0;
	for(int i=0;i<v[now].size();i++){
		if(v[now][i]!=fa){//一层层往下,不往上 
			dfs(v[now][i],now);
			if(!vis[v[now][i]])size[now]++; //没被占用可用边++ 
		}
	}
	if(size[now]==0) return;//没贡献直接返回 
	else if(size[now]%2==0) (sum*=a[size[now]])%=mod;
	else{ 
		vis[now]=1;
		(sum*=a[size[now]+1])%=mod;
	}	
}
int main(){
	cin>>n;
	a[0]=1;
	for(int i=1;i<maxn;i+=2){
		a[i+1]=a[i-1]*i;
	}
	//分组时,第i组的第一个取剩下的里最小的,第二个就有n-(2*i-1)种选择。所以是奇数相乘 
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].push_back(y);
		v[y].push_back(x);
		vis[i]=0;
	}
	vis[n]=0;
	dfs(1,0);
	cout<<sum<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_50904510/article/details/121595796