分析

我们不妨把这些座位看作是一张图中的节点,把每个人的诉求作为一条边(由【原座位】指向【想去的座位】)

比如,对于样例#1,我们就可以得到这样一张图:

显然,我们有可能会得到多个连通图(比如上面这张)

因为每个座位上的人都只有一个想去的座位,所以每个点的出度就是 \(0\)(可能只有其他的点指向它) 或 \(1\),整每个连通图的边数就是 \(n\) (点的个数)或者 \(n - 1\) 个

当边数等于 \(n\) 时,显然这是一个或者一棵基环树(定义见这里

我们以这组数据举例:

7
1 2
2 4
3 2
4 1
5 3
6 3
7 6

手画一下复制到Graph Editor,可以得到这张图:

试着移动每一个点,容易发现:移动r任意环外点(比如这里的 \(3\)、\(5\)、\(6\)、\(7\)),环上的点肯定就没位置了。

证明(废话) :点 \(2\) 唯一的一条出边已经用在环上了,所以 \(2\) 和任意环外点之间的边一定是指向 \(2\) 的,以此类推,我们可以发现:\(3\)、\(5\)、\(6\)、\(7\) 对应的边都是指向 \(2\) 的。于是,只要移动必定会移到 \(2\) 的位置

于是我们就可以得到结论:如果这是一棵基环树或者一个环,那么它的答案为 \(2\)(环内的点移/不移,两种情况)

当边数等于 \(n\) 时,显然这是一棵

我们拿它????举例:

每个节点的出度都为 \(1\) 或 \(0\)(只可能有一个点出度为 \(0\),这个座位一开始就空着),所以我们可以将唯一的那个出度为 \(0\) 的点(如这张图中的点 \(0\))作为树根。

显然,我们移动任意一个点,都会导致一种确定且不重复的情况(它到根节点的链上的每一个点都往上移),所以其答案为 \(n\),即点数

于是,最终的答案就是将每个连通图的答案乘起来。

HowTo

我们现在需要一种方法,可以判环、可以记录每个连通图的大小。

显然,并查集很合适。

每输入一个人的要求,我们就把这两个点所在的集合(连通图)合并(merge函数),同时记录集合大小(sz数组)。如果合并前这两个点已经在同一个集合中,那么,这一定是一个环(两点之间有不止一条路径),做一下标记。

最后,统计答案即可。

你以为结束了?

还有一个坑。。。

出现自环时,不能向上面那样考虑,因为这一个点移动后还在原来的位置,所以答案是 \(1\)(最终ans不变)

细节请看代码

#include <bits/stdc++.h>
using namespace std; #define int long long // 好习惯:随时开long long #define MAXN 200005
#define MOD 1000000007 // 记得取模 int n;
int fa[MAXN]; // 并查集 - 父节点
int sz[MAXN]; // 并查集 - 集合大小
bool ish[MAXN]; // is环(记录此集合是否有环)
bool iszh[MAXN]; // is自环 void init(int x) { // 并查集 - 初始化
for (int i = 1; i <= x; i++) {
fa[i] = i;
sz[i] = 1; // 初始大小都是1
}
} int find(int x) { // 并查集 - 查找
if (fa[x] == x) {
return x;
} else {
return fa[x] = find(fa[x]);
}
} void merge(int x, int y) { // 并查集 - 合并
int fx = find(x);
int fy = find(y);
if (fx == fy) { // 已经在同一个集合
return;
}
iszh[fy] |= iszh[fx]; // 合并自环信息
sz[fy] += sz[fx]; // 合并大小
fa[fx] = fy;
} signed main() {
cin >> n;
init(n * 2); // 初始化
for (int i = 1; i <= n; i++) {
int a, b;
cin >> a >> b;
if (a == b) {
iszh[find(a)] = 1; // 标记当前集合含有自环
}
if (find(a) == find(b)) { // 已经在同一个集合了
ish[find(a)] = 1; // 标记当前集合含有环
}
merge(a, b); // 连接这两个座位
}
int ans = 1;
for (int i = 1; i <= n * 2; i++) {
if (find(i) == i) { // i是一个集合的代表
if (ish[i]) { // 含有环
if (iszh[i]) { // 自环,答案不变
continue;
}
ans *= 2;
ans %= MOD;
} else { // 不含有环
ans *= sz[i];
ans %= MOD;
}
}
}
cout << ans << endl;
}

AC

CF859E 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. ZIP压缩输入/输出

    学习内容: 一.压缩文件 1.利用ZipOutputStream类对象,可将文件压缩. 2.ZipOutputStream类构造方法:ZipOutputStream(OutputStream out) ...

  2. Calico网络插件

    以下大部分是本人参考各种资料{官方文档.书籍}对知识的汇总和整理,其中有理解错误的地方请大神留言和指正,嘿嘿~~ 1.概述 参考文档:https://projectcalico.docs.tigera ...

  3. MongoDB 分片集群

    每日一句 Medalist don't grow on trees, you have to nurture them with love, with hard work, with dedicati ...

  4. 值得注意的: c++动态库、静态库、弱符号__attribute__((weak))以及extern之间的关系

    先说结论: ①:动态库优先级最差,如果同时有静态库和动态库,那么首先使用的是静态库函数. ②:如果只有两个或多个动态库,那么首先使用的是最开始链接的动态库函数: ③:弱符号函数在动态库中是起任何作用的 ...

  5. c# 简单的滑动图片验证

    普通的验证码对用户使用体验不友好,出现了滑动图片验证的验证方式,用户只要按住滑块完成图片的拼接即可通过验证(这是最简单的方式,滑动轨迹,数据分析,滑行速度 什么的暂没考虑) 主要的实现思路: 1.先从 ...

  6. go-zero 微服务实战系列(一、开篇)

    前言 在社区中经常看到有人问有没有基于 go-zero 的比较完整的项目参考,该类问题本质上是想知道基于 go-zero 的项目的最佳实践.完整的项目应该是一个完整的产品功能,包含产品需求.架构设计. ...

  7. python基础学习9

    python基础学习 内容概要 字符编码的简介 字符编码的发展史 字符编码的实际应用 文件操作简介 文件读写模式 文件操作模式 文件操作方法 内容详情 字符编码的简介 # 字符编码主要研究的对象是文本 ...

  8. 如何写出同事看不懂的Java代码?

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是没更新就是在家忙着带娃的Hydra. 前几天,正巧赶上组里代码review,一下午下来,感觉整个人都血压拉满了.五花八门的代码 ...

  9. Maven-打包jar指定main函数所在类的一个例子

    问题描述:maven打包jar时,由于带main方法的类没有被加入manifest中,导致执行java -jar mvn-jar-1.0-SNAPSHOT.jar时,会提示没有主清单属性. 解决办法: ...

  10. ssh-配置及使用

    ssh配置文件 SSH的配置文件在/etc/ssh/目录下     openssh-client安装后,生成的配置文件为ssh_config,主要用于连接其他linux主机时,加载此文件     op ...