题目大意
给定一张n ( 3 ≤ n ≤ 1 0 ^ 5 ) 个节点的树(n为奇数),将这n−1条边两两分组,
要求:分到同一组的边有相同的顶点。
求一共有多少种方法。结果对998244353取模
题解:题解
AC代码
#include<bits/stdc++.h>
using namespace std;
#define sc(x) scanf("%d",&x)
#define sl(x) scanf("%lld",&x)
#define ll long long
#define pb push_back
typedef pair<int,int>PII;
const int Max=1e6+5;
const ll INF=1e18+5;
const ll mod=998244353;
long long Power(long long base, long long power) {
long long result = 1;
while (power > 0) {
if (power & 1) {
result = result * base % mod;
}
power >>= 1;
base = (base * base) % mod;
}
return result;
}
ll dp[Max];
int vis[Max];
vector<int>mp[Max];
void dfs(int fa,int x){
int cnt=0;
for(int i=0;i<mp[x].size();i++){
int v=mp[x][i];
if(fa==v) continue;
dfs(x,v);
if(vis[v]) cnt++;
dp[x]*=dp[v];dp[x]%=mod;
}
if(cnt%2==0) vis[x]=1;
else vis[x]=0;
for(ll i=1;i<=cnt;i+=2) dp[x]*=i,dp[x]%=mod;
}
int main(){
int n;sc(n);
for(int i=1;i<=n;i++) dp[i]=1;
for(int i=0;i<n-1;i++){
int u,v;
sc(u);sc(v);
mp[u].pb(v);
mp[v].pb(u);
}
// for(int i=1;i<=n;i++) vis[i]=mp[i].size();
dfs(-1,1);
printf("%lld\n",dp[1]);
}
/*
4 1
10 1
-5 3
5 1
6 1
*/
#include<stdio.h>
#include<string.h>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define sc(x) scanf("%d",&x)
#define pb push_back
#define ll long long
using namespace std;
const int N=1e5+5,mod=998244353;
vector<int> h[N];
int f[N];
bool dfs(int u,int fa)
{
f[u]=1;
int cnt=0;
for(int v:h[u])
{
if(v==fa) continue;
if(!dfs(v,u)) cnt++;
f[u]=(ll)f[u]*f[v]%mod;
}
for(int i=1;i<=cnt;i+=2) f[u]=(ll)f[u]*i%mod;
return cnt&1;
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
h[u].push_back(v);
h[v].push_back(u);
}
dfs(1,-1);
cout<<f[1]<<endl;
return 0;
}