canvas dClock
您的浏览器太古董了,升级吧!

CF 859 E

CF 859 E

Solution

首先将原来的向想要的位置连边,就会变成这个样子:

  • 一棵树

  • 一棵树加根上多一条反向边

如果是一棵树,那么答案乘上这棵树的大小.

如果是一棵树加上一条反向边,那么

  1. 反向边是一个自环,不对答案产生贡献.

  2. 反向边不是自环,答案$\times$2

ed.

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
const int MAXN=100000;
const int MOD=1e9+7;
int n;
int fa[2*MAXN+10],sz[2*MAXN+10];
bool flag[2*MAXN+10];
int find(int x){return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=2*n;++i)fa[i]=i,sz[i]=1;
	int res=1;
	for(int i=1,a,b;i<=n;++i)
	{
		scanf("%d%d",&a,&b);
		if(find(a)!=find(b))
		{
			sz[find(b)]+=sz[find(a)];
			fa[find(a)]=fa[find(b)];
		}
		else
		{
			flag[find(a)]=true;
			if(a!=b)res=(ll)res*2%MOD;
		}
	}
	for(int i=1;i<=2*n;++i)if(fa[i]==i&&!flag[i])res=(ll)res*sz[i]%MOD;
	printf("%d",res);
	return 0;
}
posted @ 2017-09-18 19:33  DOlaBMOon  阅读(1011)  评论(0编辑  收藏  举报