N年没写题解于是一时兴起就来写一下
先考虑无解情况
如果有点度数>2那肯定无解 还有 环的情况也会无解
那么度数为1或2的点 他们肯定是连成一条条的链
这些链的组合方案只有2种 就是只能翻转一下
答案就是 (度数为0的点数+链数)! * (2^链数)
代码可能不够美观?(貌似并不快)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=500010,mod=989381;
inline int read(){
int 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<<1)+(x<<3)+ch-'0'; ch=getchar();}
return x*f;
}
vector<int>v[N];
LL jc[N];
bool b[N];
struct node{int x,la;};
queue<node>q;
int main(){
int n=read(),m=read(),i;
jc[0]=1; for(i=1;i<=n;++i)jc[i]=jc[i-1]*i%mod;
for(i=1;i<=m;++i){
int x=read(),y=read(); bool o=0;
for(int j=0;j<v[x].size();++j)
if(v[x][j]==y){o=1; break;}
if(o)continue;
v[x].push_back(y);
v[y].push_back(x);
}
int cnt=0,u=0; LL ans=1;
bool no=0;
for(i=1;i<=n;++i)
if(v[i].size()>2){no=1; break;}
if(no){printf("0\n"); return 0;}
for(i=1;i<=n;++i) if(!b[i] && v[i].size()==2){
q.push((node){i,0}); b[i]=1; ++u,++cnt;
while(!q.empty()){
node x=q.front(); q.pop();
for(int j=0;j<v[x.x].size();++j){
int y=v[x.x][j];
if(b[y] && y!=x.la){no=1; break;}
if(!b[y]){b[y]=1; ++u; q.push((node){y,x.x});}
}
if(no)break;
}
if(no)break;
ans=ans*2%mod;
}
if(no){printf("0\n"); return 0;}
for(i=1;i<=n;++i) if(!b[i] && v[i].size()==1){
b[i]=b[v[i][0]]=1,++cnt;
u+=2,ans=ans*2%mod;
}
ans=ans*jc[cnt+(n-u)]%mod;
printf("%lld\n",ans);
return 0;
}