Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂
题目链接:http://codeforces.com/problemset/problem/711/D
2 seconds
256 megabytes
standard input
standard output
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.
3
2 3 1
6
4
2 1 1 1
8
5
2 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-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 2e5+; int n, a[maxn];
int vis[maxn], group[maxn];
LL ans; LL qpow(LL x, LL y)
{
LL s = ;
while(y)
{
if(y&) s = (s*x)%mod;
x = (x*x)%mod;
y >>= ;
}
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(,cnt-vis[a[k]]+)-, ans %= mod; //环的部分
ans *= qpow(, vis[a[k]]-), ans %= mod; // 环之外的那条线
}
else ans *= qpow(,cnt), ans %= mod; //dfs出线丝
}
else dfs(a[k], id, cnt+);
} int main()
{
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%d",&a[i]); ans = ;
ms(vis,);
ms(group,);
for(int i = ; i<=n; i++)
if(!vis[i])
dfs(i,i,); printf("%lld\n", ans);
}
Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂的更多相关文章
- Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量
D. Directed Roads ZS the Coder and Chris the Baboon has explored Udayland for quite some time. The ...
- Codeforces Round #369 (Div. 2) D. Directed Roads (DFS)
D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- Codeforces Round #369 (Div. 2) D. Directed Roads 数学
D. Directed Roads 题目连接: http://www.codeforces.com/contest/711/problem/D Description ZS the Coder and ...
- Codeforces Round #369 (Div. 2)-D Directed Roads
题目大意:给你n个点n条边的有向图,你可以任意地反转一条边的方向,也可以一条都不反转,问你有多少种反转的方法 使图中没有环. 思路:我们先把有向边全部变成无向边,每个连通图中肯定有且只有一个环,如果这 ...
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations 矩阵快速幂优化dp
D. GukiZ and Binary Operations time limit per test 1 second memory limit per test 256 megabytes inpu ...
- Codeforces Round #209 (Div. 2)A贪心 B思路 C思路+快速幂
A. Table time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- CodeForces 711D Directed Roads (DFS找环+组合数)
<题目链接> 题目大意: 给定一个$n$条边,$n$个点的图,每个点只有一条出边(初始状态),现在能够任意对图上的边进行翻转,问你能够使得该有向图不出先环的方案数有多少种. 解题分析: 很 ...
- Codeforces Round #302 (Div. 2) D - Destroying Roads 图论,最短路
D - Destroying Roads Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544 ...
- Codeforces Round #369 (Div. 2)---C - Coloring Trees (很妙的DP题)
题目链接 http://codeforces.com/contest/711/problem/C Description ZS the Coder and Chris the Baboon has a ...
随机推荐
- 缓存区溢出漏洞工具Doona
缓存区溢出漏洞工具Doona Doona是缓存区溢出漏洞工具BED的分支.它在BED的基础上,增加了更多插件,如nttp.proxy.rtsp.tftp等.同时,它对各个插件扩充了攻击载荷,这里也 ...
- spring mvc表单的展现、输入处理、校验的实现
之前已经实现了spring mvc的入门例子及如何处理带参数的请求Controller编写.本文主要记录: 1)重定向请求 2)处理路径中含有变量的请求 3)使用JSR-303进行校验 ① 首先,编写 ...
- mysql事务四种隔离级别
事务的基本要素:原子性,一致性,隔离性,持久性. 事务并发问题:脏读,不可重复读,幻读. mysql隔离级别:read-uncommitted,read-committed,repeatable-re ...
- Java文件夹操作,判断多级路径是否存在,不存在就创建(包括windows和linux下的路径字符分析),兼容Windows和Linux
兼容windows和linux. 分析: 在windows下路径有以下表示方式: (标准)D:\test\1.txt (不标准,参考linux)D:/test/1.txt 然后在java中,尤其使用F ...
- array_map常用技巧
array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组. 简单来说 “array_map” 会对数组中的每一项进行处理,并返回处理后的数据. 定 ...
- python matplotlib 绘图 和 dpi对应关系
dpi=1 600×400 dpi=2 1200×800 dpi=3 1800×1200 ........ dpi=21 (21×600)×(21×400) ---> 12600×8400 示例 ...
- 深入理解vue路由的使用
vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来.传统的页面应 ...
- 【windows socket+UDPserverclient】
Windows Socket+UDPserverclient Winsock是 Windows下套接字标准. 1.UDP socket编程: ...
- 用ELK 实时处理搜索日志
转载请标明原处:http://blog.csdn.net/hu948162999/article/details/50563110 本来这块业务 是放到SolrCloud上去的 , 然后 採用solr ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...