Solution
首先将原来的向想要的位置连边,就会变成这个样子:
-
一棵树
-
一棵树加根上多一条反向边
如果是一棵树,那么答案乘上这棵树的大小.
如果是一棵树加上一条反向边,那么
-
反向边是一个自环,不对答案产生贡献.
-
反向边不是自环,答案$ imes$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;
}