3444: 最后的晚餐
https://www.lydsy.com/JudgeOnline/problem.php?id=3444
分析:
计数。
首先判断无解的情况,因为这是一张长桌子,所以出现了环无解,然后并查集判环。如果是两个人之间的环,可以跳过。因为每个人只能和两个人挨着,所以三个及三个以上都想和一个人挨着,那么无解。
然后就成了很多条序列,往一个大的序列上放,那么全排列为$A^n_n$,即n!。对于每个序列,它又有两种方法排列,(长度为1的只有一种),然后再乘以2。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int mod = 989381; 11 const int N = 500100; 12 13 int fa[N], du[N], cnt[N], L[N]; 14 15 int find(int x) { 16 return x == fa[x] ? x : fa[x] = find(fa[x]); 17 } 18 19 int main() { 20 21 int n = read(), m = read(), tot = 0; 22 for (int i=1; i<=n; ++i) fa[i] = i; 23 24 for (int t1,t2,i=1; i<=m; ++i) { 25 int u = read(), v = read(); 26 if (u == L[v]) continue; 27 28 if ((t1=find(u)) == (t2=find(v)) || du[u] >= 2 || du[v] >= 2) { 29 puts("0");return 0; 30 } 31 32 L[u] = v; 33 du[u] ++, du[v] ++; // du[t1]++ , du[t2]++ 34 fa[t1] = t2; 35 } 36 37 LL ans = 1; 38 39 for (int i=1; i<=n; ++i) cnt[find(i)] ++; 40 41 for (int i=1; i<=n; ++i) { 42 if (cnt[i]) { 43 if (cnt[i] > 1) ans = (ans * 2) % mod; 44 tot ++; 45 } 46 } 47 48 for (int i=1; i<=tot; ++i) ans = (ans * i) % mod; 49 50 cout << ans; 51 52 return 0; 53 }