题意:
给出n点m边的无向图,将其中的边变为有向边使得其满足对于每个点来说有且只有一个出边,求方案数。
思路:
首先,每个连通块都是独立的,所以分别考虑每个连通块的方案数,最后相乘即可。
其次,对于每个连通块,只有边数跟点数相同时,才会有合法的方案,为2种。
比如:
4 4
1 2
2 3
3 4
2 4
有下面两种方案:
1->2,2->3,3->4,4->2
1->2,2->4,4->3,3->2
如果有一个连通块没有合法的方案数,答案为0
代码:
// Problem: E - Just one // Contest: AtCoder - AtCoder Beginner Contest 226 // URL: https://atcoder.jp/contests/abc226/tasks/abc226_e // Memory Limit: 1024 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; typedef long long ll;typedef unsigned long long ull; typedef pair<ll,ll>PLL;typedef pair<int,int>PII;typedef pair<double,double>PDD; #define I_int ll inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} #define read read() #define rep(i, a, b) for(int i=(a);i<=(b);++i) #define dep(i, a, b) for(int i=(a);i>=(b);--i) ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;} const int maxn=4e5+7,maxm=1e6+7,mod=998244353; int n,m,vis[maxn]; vector<int>g[maxn]; int cnt_e,cnt_v; void dfs(int u){ cnt_v++; cnt_e+=g[u].size(); vis[u]=1; for(int tt:g[u]){ if(!vis[tt]) dfs(tt); } } int main(){ n=read,m=read; rep(i,1,m){ int u=read,v=read; g[u].push_back(v); g[v].push_back(u); } ll sum=0,flag=1; rep(i,1,n){ if(!vis[i]){ cnt_e=cnt_v=0; dfs(i); if(cnt_e==cnt_v*2) sum++; else flag=0; } } if(!flag) puts("0"); else cout<<ksm(2,sum,mod); return 0; }