bzoj3444

转为图论 把一个暗恋关系变成双向边(因为两个人要在一起,所以要记得去重),加边时顺带统计入度,>2不合法,若有环也不合法,如果有答案,即排列数,要处理可翻转的情况

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<ctime>
 5 #include<cmath>
 6 #include<iostream>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<stack>
10 #include<set>
11 #define clr(a,x) memset(a,x,sizeof(a))
12 #define rep(i,l,r) for(int i=(l);i<(r);i++)
13 using namespace std;
14 typedef long long ll;
15 typedef pair<int,int> pii;
16 #define mkp(a,b) make_pair(a,b)
17 int read(){
18     int ans=0,f=1;
19     char c=getchar();
20     while(!isdigit(c)){
21         if(c=='-') f=-1;
22         c=getchar();
23     }
24     while(isdigit(c)){
25         ans=ans*10+c-'0';
26         c=getchar();
27     }
28     return ans*f;
29 }
30 const int maxn=500009,mod=989381;
31 int cnt,n,m,w[maxn],in[maxn];
32 pii e[maxn<<1];
33 bool vis[maxn];
34 struct edge{
35     int v;
36     edge*next;
37 }E[maxn<<1],*fir[maxn],*pt=E;
38 void addedge(int u,int v){
39     in[pt->v=v]++;
40     pt->next=fir[u];
41     fir[u]=pt++;
42 }
43 bool dfs(int x,int f){
44     if(vis[x]) return 1;
45     vis[x]=1;w[cnt]++;
46     for(edge*e=fir[x];e;e=e->next){
47         if(e->v!=f&&dfs(e->v,x)) return 1;
48     }
49     return 0;
50 }
51 int main(){
52     n=read();m=read();
53     rep(i,0,m){
54         e[i<<1].first=e[i<<1|1].first=read();
55         e[i<<1].second=e[i<<1|1].second=read();
56         swap(e[i<<1].first,e[i<<1].second);
57     }
58     sort(e,e+m*2);
59     m=unique(e,e+m*2)-e;
60     rep(i,0,m) addedge(e[i].first,e[i].second);
61     rep(i,1,n+1) if(in[i]>2){
62         puts("0");return 0;
63     }
64     rep(i,1,n+1) if(!vis[i]){
65         ++cnt;
66         if(dfs(i,-1)){
67             puts("0");return 0;
68         }
69     }
70     ll ans=1;
71     rep(i,1,cnt+1) ans=ans*ll(i)%mod;
72     rep(i,1,cnt+1) if(w[i]>1&&((ans<<=1)>=mod)) ans-=mod;
73     cout<<ans<<endl;
74     return 0;
75 }
View Code

3444: 最后的晚餐

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 344  Solved: 129
[Submit][Status][Discuss]

Description

【问题背景】
高三的学长们就要离开学校,各奔东西了。某班n人在举行最后的离别晚餐时,饭店老板觉得十分纠结。因为有m名学生偷偷找他,要求和自己暗恋的同学坐在一起。
【问题描述】
饭店给这些同学提供了一个很长的桌子,除了两头的同学,每一个同学都与两个同学相邻(即坐成一排)。给出所有信息,满足所有人的要求,求安排的方案总数(这个数字可能很大,请输出方案总数取余989381的值,也可能为0)。

Input

输入有m+1行,第一行有两个用空格隔开的正整数n、m,如题所示。接下来的m行,每一行有两个用空格隔开的正整数,第i行为Ai和Bi,表示Ai的暗恋对象为Bi,保证Ai互不相等。

Output

输出只有一行,这一行只有一个数字,如题所示。

Sample Input

4 2
1 2
4 3

Sample Output

8


【数据范围】
100%的数据,0<n≤500000,1≤Ai,Bi≤n,0≤m≤n,保证没有人自恋。

HINT

 

Source

[Submit][Status][Discuss]
原文地址:https://www.cnblogs.com/chensiang/p/4992962.html