题解:P11380 [GESP202412 八级] 排队

赛时一秒出思路,半小时调代码,把我给干红温了。

Solution P11380

Idea

对于一条限制关系 (ai,bi)(a_i,b_i),我们将其看作 aia_ibib_i 连边。

那么我们可以发现以下的情况是不合法的:

  • 图上有环。这是一个序列,哪里来的环。
  • 一个点有多条出边。一个人右边只有一个位置,哪里安的下两个人。

判断完特殊情况,不难发现这个图有很多连通块,根据乘法原理,若连通块数为 cntcnt,则答案为 1×2×3××(cnt1)×cnt1\times 2\times 3\times \cdots \times (cnt-1) \times cnt

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=200005;
int nxt[N],vis[N],n,m,pre[N],cnt;
void dfs(int now){
	if(now==0)return;
	if(vis[now]){
		printf("0");
		exit(0); 
	}
	vis[now]=1;
	dfs(nxt[now]);
}
main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%lld%lld",&u,&v);
		if(nxt[u]!=0&&nxt[u]!=v){
			printf("0");
			return 0;
		}
		nxt[u]=v;
		pre[v]=u;
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]&&pre[i]==0){//找入度为 0 的点遍历,不然可能遍历不完整张图
			dfs(i);
			cnt++;
		}
	}
	if(cnt==0){
		printf("0");
		return 0;
//如果整个图只有一个环,上面 dfs 找不到。在这里特判
	}
	long long ans=1;
	for(int i=1;i<=cnt;i++)ans=ans*i%1000000007;
	printf("%lld",ans);
}
posted @ 2024-12-10 16:42  Weslie_qwq  阅读(47)  评论(0)    收藏  举报  来源