题目链接: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();
}

Codeforces 859E Desk Disorder:并查集【两个属性二选一】的更多相关文章

  1. Codeforces 859E Desk Disorder 并查集找环,乘法原理

    题目链接:http://codeforces.com/contest/859/problem/E 题意:有N个人.2N个座位.现在告诉你这N个人它们现在的座位.以及它们想去的座位.每个人可以去它们想去 ...

  2. Codeforces 870E Points, Lines and Ready-made Titles:并查集【两个属性二选一】

    题目链接:http://codeforces.com/problemset/problem/870/E 题意: 给出平面坐标系上的n个点. 对于每个点,你可以画一条经过这个点的横线或竖线或什么都不画. ...

  3. Codeforces Gym 100463E Spies 并查集

    Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Desc ...

  4. Codeforces 571D - Campus(并查集+线段树+DFS 序,hot tea)

    Codeforces 题目传送门 & 洛谷题目传送门 看到集合的合并,可以本能地想到并查集. 不过这题的操作与传统意义上的并查集不太一样,传统意义上的并查集一般是用来判断连通性的,而此题还需支 ...

  5. CodeForces 455C Civilization (并查集+树的直径)

    Civilization 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/B Description Andrew plays a ...

  6. Codeforces 468B Two Sets 并查集

    题目大意:给出n个数,要求将n个数分配到两个集合中,集合0中的元素x,要求A-x也再0中,同理1集合. 写了几个版本号,一直WA在第8组数据...最后參考下ans,写了并查集过了 学到:1.注意离散的 ...

  7. CF 859E Desk Disorder

    题目大意:一个经典的游戏:抢椅子.有\(n\)个人以及\(2n\)把椅子.开始时每个人坐在一把椅子上,而且他们每个人都有一个下一步想坐的位置(可以与之前重合).每一个下一次可以在自己现在做的椅子和想坐 ...

  8. CodeForces 455C Civilization(并查集+树直径)

    好久没有写过图论的东西了,居然双向边要开两倍空间都忘了,不过数组越界cf居然给我报MLE??这个题题意特别纠结,一开始一直不懂添加的边长是多长... 题意:给你一些点,然后给一些边,注意没有重边 环, ...

  9. Codeforces - 828C String Reconstruction —— 并查集find()函数

    题目链接:http://codeforces.com/contest/828/problem/C C. String Reconstruction time limit per test 2 seco ...

随机推荐

  1. shell中${}的使用

    1. 截断功能${file#*/}:       拿掉第一条/及其左边的字符串:dir1/dir2/dir3/my.file.txt${file##*/}:    拿掉最后一条/及其左边的字符串:my ...

  2. 关于Apache Shiro权限框架的一些使用误区的解释

    多了不说了,进入正题,shiro是个权限框架提供权限管理等功能,网上的教程一般都是互相抄,比如<shiro:principal property="xxx"/>这个标签 ...

  3. 机器重启 查看crontab执行历史记录crontab没有执行

    Sep 17 19:01:01 d run-parts(/etc/cron.hourly)[8452]: finished 0anacronSep 17 19:10:01 d CROND[9059]: ...

  4. hctf2016 fheap学习(FreeBuf发表的官方解法)

    目录 如何在二次释放前修改函数指针 修改函数指针流程 如何获得进程的加载基址 puts函数的调用 如何获取system函数地址 说一下用DlyELF函数 如何调用system函数 ROP需要的栈布局 ...

  5. delphi下webbrowser的应用

    查找操作tagName为input的对象var i:Integer; myole:oleVariant; begin myole := wb1.Document; for i := 0 to myol ...

  6. dataTables的导出Excel功能

    Datatables它是一款基于jQuery表格插件,钟情于它操作dom的灵活.做后台的同学想必使用它能事半功倍,而且交互强.容易扩展. 我也是最近要做公司后台界面,表格涉及的很多,所以考虑使用DT, ...

  7. 修改mysql root的密码

    use mysql:update user set Password = Password('newPwd') where user='root';//更改root用户的密码flush privile ...

  8. 201704 F-47创建预付款申请a

    应该也是用 BAPI_ACC_DOCUMENT_POST

  9. C#(ASP.NET)隐藏或显示Excel中指定列

    今天写的一个方法,实现Excel指定列的隐藏和显示: 环境:VS2010,OFFICE 2010 代码:#region 隐藏和显示Excel中的一列        /// <summary> ...

  10. C#对excel的操作

    本文先描述如何用c#连接.操作excel文件. 项目中需要引入的DLL文件为Interop.Excel.Interop.Microsoft.Office.Core.Interop.Office等. 操 ...