题目链接:http://codeforces.com/problemset/problem/859/E

题意:

  有n个人,2n个座位。

  给出这n个人初始的座位,和他们想坐的座位。

  每个人要么坐在原来的位置不动,要么坐到想坐的座位上,但是不能有两个人坐在同一个座位上。

  问你合法的安排座位的方案数。

题解:

  将2n个座位抽象成2n个点。

  对于每个人,从他的初始位置向想坐的位置连一条边。

  总答案即为所有连通块答案的乘积。

  由于每一个点最多向外连一条边,所以对于每一个连通块只有三种情况:

    (1)是一棵树,根节点不自环,且所有边的方向都是由儿子指向父亲。

    (2)是一棵树,根节点自环,且所有边的方向都是由儿子指向父亲。

    (3)有且只有一个环。

  对于这三种情况,可以发现:

    (1)方案数 = 连通块大小siz[fa]

    (2)方案数 = 1

    (3)方案数 = 2

  并查集维护一下,最后统计答案即可。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX_N 200005
#define MOD 1000000007 using namespace std; int n;
int par[MAX_N];
int siz[MAX_N];
bool tag[MAX_N];
bool loop[MAX_N];
long long ans=; void init_union_find()
{
for(int i=;i<=(n<<);i++)
{
par[i]=i;
siz[i]=;
tag[i]=false;
loop[i]=false;
}
} int find(int x)
{
return par[x]==x ? x : par[x]=find(par[x]);
} void unite(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py)
{
tag[px]=true;
return;
}
siz[py]+=siz[px];
tag[py]|=tag[px];
par[px]=py;
} void read()
{
cin>>n;
init_union_find();
int x,y;
for(int i=;i<=n;i++)
{
cin>>x>>y;
unite(x,y);
if(x==y) loop[x]=true;
}
} void work()
{
for(int i=;i<=(n<<);i++)
{
if(find(i)==i)
{
if(loop[i]) continue;
if(tag[i]) ans=(ans<<1ll)%MOD;
else ans=ans*siz[i]%MOD;
}
}
cout<<ans<<endl;
} int main()
{
read();
work();
}

最新文章

  1. html5开发移动页面去掉点击出现的透明阴影----&amp;&amp;-----元素垂直居中
  2. C#知识点总结系列:C# 数据结构
  3. 搭建java环境
  4. 比较核心的技术了 虚拟ip的一种实现方式(手工添加和C#添加)
  5. JavaScript DOM 编程艺术(第2版)读书笔记(2)
  6. [hadoop] 集群启动和内存调优
  7. NOJ1142-最大连续和
  8. C# div、css
  9. java线程的实现
  10. spring AOP原理
  11. [知了堂学习笔记]_牵线Eclipse和Tomcat第一篇 —— 配置Java环境变量&amp;&amp;安装eclipse
  12. 深入浅出的webpack构建工具---PostCss(五)
  13. Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs)
  14. 【WPF】右键菜单ContextMenu可点击区域太小的问题
  15. [C#]跨模块的可选参数与常量注意事项
  16. Spring面试 IOC和AOP的理解
  17. shipyard 中文版安装 -- Docker web管理
  18. spark(oom内存溢出异常(out of memory))介绍1
  19. IOS开发之自定义键盘
  20. COGS 2638. 数列操作ψ 线段树

热门文章

  1. django restframework 的日常使用
  2. distinct与NULL在count的注意事项
  3. &lt;2013 08 26&gt; 雅思听力相关
  4. laydate日历控件
  5. JavaWeb 之监听器
  6. git学习------>git commit命令的默认编辑器的修改
  7. Java语言实现简单FTP软件------>FTP软件主界面的实现(四)
  8. 0405-服务注册与发现-客户端负载均衡-Ribbon 同Eureka使用,Ribbon脱离Eureka使用
  9. 常用python模块
  10. 曾经跳过的坑------replace、替换斜杠反斜杠、时间格式化处理