Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂
来源:互联网 发布:mac 获取当前路径 编辑:程序博客网 时间:2024/06/06 05:02
题目链接:http://codeforces.com/problemset/problem/711/D
ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it consists of n towns numbered from 1 to n.
There are n directed roads in the Udayland. i-th of them goes from town i to some other town ai (ai ≠ i). ZS the Coder can flip the direction of any road in Udayland, i.e. if it goes from town A to town B before the flip, it will go from town B to town A after.
ZS the Coder considers the roads in the Udayland confusing, if there is a sequence of distinct towns A1, A2, ..., Ak (k > 1) such that for every 1 ≤ i < k there is a road from town Ai to town Ai + 1 and another road from town Ak to town A1. In other words, the roads are confusing if some of them form a directed cycle of some towns.
Now ZS the Coder wonders how many sets of roads (there are 2n variants) in initial configuration can he choose to flip such that after flipping each road in the set exactly once, the resulting network will not be confusing.
Note that it is allowed that after the flipping there are more than one directed road from some town and possibly some towns with no roads leading out of it, or multiple roads between any pair of cities.
The first line of the input contains single integer n (2 ≤ n ≤ 2·105) — the number of towns in Udayland.
The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n, ai ≠ i), ai denotes a road going from town i to town ai.
Print a single integer — the number of ways to flip some set of the roads so that the resulting whole set of all roads is not confusing. Since this number may be too large, print the answer modulo 109 + 7.
32 3 1
6
42 1 1 1
8
52 4 2 5 3
28
Consider the first sample case. There are 3 towns and 3 roads. The towns are numbered from 1 to 3 and the roads are , , initially. Number the roads 1 to 3 in this order.
The sets of roads that ZS the Coder can flip (to make them not confusing) are {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}. Note that the empty set is invalid because if no roads are flipped, then towns 1, 2, 3 is form a directed cycle, so it is confusing. Similarly, flipping all roads is confusing too. Thus, there are a total of 6 possible sets ZS the Coder can flip.
The sample image shows all possible ways of orienting the roads from the first sample such that the network is not confusing.
题解:
1.根据题意, n个点共有n条边。那么表明每个连通块中, 有且仅有一个环, 且这个环可能还有一些“线丝”挂在上面。
2.首先对于一个连通块而言, 可分为环部分和线丝部分:对于环部分,如果有k个点, 那么有(1<<k)-2种情况可以去环。(-2是减去所有都flip或者所有都不flip这两种情况,因为这两种情况都不能 去环), 对于线丝部分, 他们的状态对环没有影响,假设线丝有t个点,那么状态数为1<<t。
最后将每个连通块的环部分和线丝部分的状态数相乘, 即为答案。
找环问题:
1.group[]数组记录当前点时是在哪一次的dfs中访问到的。vis[]记录当前点在这次dfs中是第几个被访问的元素。
2.在dfs的过程中, 当遇到被访问过的元素时: 如果它的group[i]为这次dfs所标记的, 那么表明这次dfs构成了环; 如果group[i]为之前dfs所标记的, 那么表明这次dfs出来的是线丝(遇到的连通块必定有环。因为:假设无环,那么就可以dfs出环了,说明假设不成立)。
代码如下:
#include<bits/stdc++.h>#define ms(a, b) memset((a), (b), sizeof(a))using namespace std;typedef long long LL;const double eps = 1e-6;const int INF = 2e9;const LL LNF = 9e18;const int mod = 1e9+7;const int maxn = 2e5+10;int n, a[maxn];int vis[maxn], group[maxn];LL ans;LL qpow(LL x, LL y){ LL s = 1; while(y) { if(y&1) s = (s*x)%mod; x = (x*x)%mod; y >>= 1; } return s;}void dfs(int k, int id, int cnt) //dfs出环, 或者dfs出线丝{ vis[k] = cnt; group[k] = id; if(vis[a[k]]) //遇到了被访问过的元素 { if(group[a[k]]==id) //dfs出环 { ans *= qpow(2,cnt-vis[a[k]]+1)-2, ans %= mod; //环的部分 ans *= qpow(2, vis[a[k]]-1), ans %= mod; // 环之外的那条线 } else ans *= qpow(2,cnt), ans %= mod; //dfs出线丝 } else dfs(a[k], id, cnt+1);}int main(){ scanf("%d",&n); for(int i = 1; i<=n; i++) scanf("%d",&a[i]); ans = 1; ms(vis,0); ms(group,0); for(int i = 1; i<=n; i++) if(!vis[i]) dfs(i,i,1); printf("%lld\n", ans);}
- Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂
- Codeforces Round #369 (Div. 2) -- D. Directed Roads (DFS找环)
- Codeforces Round #369 (Div. 2) 711D Directed Roads (dfs)
- 【Codeforces Round #369 (Div. 2)】Codeforces 711D Directed Roads
- Codeforces Round #369 (Div. 2) D. Directed Roads (dfs+组合数学 图论)
- 有向图找环——Directed Roads ( Codeforces Round #369 (Div. 2) D )
- Codeforces Round #369 (Div. 2) [D] Directed Roads
- Codeforces Round #369 (Div. 2) D. Directed Roads
- Codeforces 711D Directed Roads dfs(找环)
- cf#369-D - Directed Roads-dfs找环
- codeforces 711D. Directed Roads 找环
- [Codeforces Round #369 (Div. 2)D. Directed Roads]Tarjan强连通分量+组合计数
- Codeforces Round #369 (Div. 2) D. Directed Roads 图论、组合学、二重dfs、并查集形式的图、Interesting、好题
- 【Codeforces 711 D D. Directed Roads】 + DFS
- codeforces 711D Directed Roads(DFS)
- Codeforces 711D Directed Roads【Dfs+思维】
- Codeforces Round #369 (Div. 2) D DFS
- Codeforces #369 div2 D.Directed Roads
- 关于二叉树的面试题
- 按行拼接两个txt文件的python实现
- 玩具装箱toy
- 高颜值智能备忘录:不再遗忘任何要事
- [bzoj3876][AHOI2014]支线剧情 有下界费用流
- Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂
- 在Python中出现IndentationError: unexpected indent
- 【react学习】关于react框架使用的一些细节要点的思考
- Q学习的局限性
- jtable隐藏列
- 将数据集做成VOC2007格式用于Faster-RCNN训练
- Yii中render和renderPartial的区别
- 【POJ1160】【四边形优化DP】Post Office
- UVA 839 Not So Mobile 【递归+树】