高三的學長們就要離開學校,各奔東西了。某班n人在舉行最後的離別晚餐時,飯店老闆覺得十分糾結。因爲有m名學生偷偷找他,要求和自己暗戀的同學坐在一起。
【問題描述】
飯店給這些同學提供了一個很長的桌子,除了兩頭的同學,每一個同學都與兩個同學相鄰(即坐成一排)。給出所有信息,滿足所有人的要求,求安排的方案總數(這個數字可能很大,請輸出方案總數取餘989381的值,也可能爲0)。
#include <cstdio>
#include <algorithm>
#include <map>
#define rep(i,l,r) for (int i=l;i<=r;++i)
typedef long long LL;
int getx(){
char c;int x;
for (c=getchar();c<'0'||c>'9';c=getchar());
for (x=0;c>='0'&&c<='9';c=getchar())
x=(x<<3)+(x<<1)+c-'0';
return x;
}
const LL MOD=989381;
const int MAX_N=500005;
int first[MAX_N],next[MAX_N<<1],to[MAX_N<<1];
int rd[MAX_N];
int tal=0;
void tjb(int x,int y){
next[++tal]=first[x];
first[x]=tal;
to[tal]=y;
rd[y]++;
}
int tot=0;
bool vis[MAX_N];
void topo(int v,int fa){
vis[v]=true;tot--;
for (int k=first[v];k;k=next[k]){
int u=to[k];
if (u==fa) continue;
if (--rd[u]<=1) topo(u,v);
}
}
LL power(LL a,LL b){
LL res=1;
for (;b;a=((LL)a*a)%MOD,b>>=1)
if (b&1) res=((LL)res*a)%MOD;
return res;
}
int n,m;
std::map<int,bool> edge[MAX_N];
bool choose[MAX_N];
int main(){
n=getx(),m=getx();
rep(i,1,m){
int x=getx(),y=getx();
if (x>y) x^=y,y^=x,x^=y;
if (!choose[x]){choose[x]=true;tot++;}
if (!choose[y]){choose[y]=true;tot++;}
if (!edge[x][y]){
tjb(x,y),tjb(y,x);
if (rd[x]>2||rd[y]>2) {printf("0");exit(0);}
edge[x][y]=true;
}
}
int s=n-tot;
int k=0;
rep(i,1,n)
if (!vis[i]&&rd[i]==1){k++;topo(i,0);}
if (tot>0){printf("0");exit(0);}
LL ans=1;
rep(i,1,s+k) ans=ans*i%MOD;
printf("%d\n",ans*power(2,k)%MOD);
}