CodeForces #369 div2 D Directed Roads DFS
题目链接:D Directed Roads
题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边。这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方向反转),使得这个图里没有环。
思路:感觉关键是,n个点n条边,且每个点的出度为1,所以图里一定没有复环。想要使图里没环,对于每个连通块(点数为i)里的环(如果有环 点数为j),只要不是全翻和全不翻都是满足题意的set,
一共满足题意得set 即为 2^(i-j) * (2^j-2)。所有的连通块方案相乘即为最后的方案数ans.
找到所有的连通块并且得到里面的环的点数:邻接表存图dfs遍历连通块,全局变量标记当前连通块的点数,设置num数组标记每个点被访问时的次序,当再次被访问到时,两次标号相减
即为环的点数。但是这样的样例:
4
2 1 1 1
搜出来的环数会是1,因为3和4搜到1的时候确实1已经被标记了。而且覆盖了前面的2。然后... ... 本来想着先过样例吧...就在所有找到的环数里取max,觉得一定不对,比如这样:
10
2 1 1 1 1 1 1 1 1 1
居然是对的。
然后最后的ans被莫名其妙的%mod爆int。
附AC代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#define maxn 2000100
#define LL long long
using namespace std;
const LL mod = 1e9+7; struct Node {
int u, v;
int nxt;
}edge[maxn]; //边数 int tot;
LL ans;
int num[maxn];
int numCir;
LL pow2[maxn];
int cntt;
int head[maxn];
bool vis[maxn]; void init() {
memset(num, 0, sizeof(num));
ans = 1;
tot = 0;
numCir = 0;
memset(head, -1, sizeof(head));
pow2[0] = 1;
for (int i=1; i<=maxn; ++i) {
pow2[i] = (pow2[i-1]*2)%mod;
}
// memset(vis, 0, sizeof(vis));
} void addEdge(int u, int v) {
edge[tot].u = u;
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
} void dfs(int id, int cnt) {
cntt++;
//cout << id << "@+++++" << cntt << endl;
for (int i=head[id]; i!=-1; i=edge[i].nxt) {
int v = edge[i].v;
if (!vis[v]) {
num[v] = cnt+1;
vis[v] = 1;
dfs(v, cnt+1);
}
else { ///找到环了
numCir = max(cnt + 1 - num[v], numCir);
}
}
///搜完了整个连通块
} int main() {
//freopen("in.cpp", "r", stdin);
int n;
while(~scanf("%d", &n)) {
init();
// build map
for (int i=1; i<=n; ++i) {
int temp;
scanf("%d", &temp);
addEdge(i, temp);
addEdge(temp, i);
}
memset(vis, 0, sizeof(vis)); for (int i=1; i<=n; ++i) {
//cout << i << "@\n";
if (vis[i]) continue;
vis[i] = 1;
num[i] = 1;
cntt = 0;
numCir = 0;
dfs(i, 1);
// cout << numCir << " " << cntt << endl;
if (numCir == 0) ans += pow2[cntt];
else ans = (ans * ((pow2[cntt-numCir]*(pow2[numCir]-2))%mod))%mod;
}
ans %= mod;
printf("%I64d\n", ans);
}
return 0;
}
CodeForces #369 div2 D Directed Roads DFS的更多相关文章
- Codeforces #369 div2 D.Directed Roads
D. Directed Roads time limit per test2 seconds memory limit per test256 megabytes inputstandard inpu ...
- Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂
题目链接:http://codeforces.com/problemset/problem/711/D D. Directed Roads time limit per test 2 seconds ...
- 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 711D D. Directed Roads(dfs)
题目链接: D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- Codeforces 711 D. Directed Roads (DFS判环)
题目链接:http://codeforces.com/problemset/problem/711/D 给你一个n个节点n条边的有向图,可以把一条边反向,现在问有多少种方式可以使这个图没有环. 每个连 ...
- CodeForces 711D Directed Roads (DFS判环+计数)
题意:给定一个有向图,然后你可能改变某一些边的方向,然后就形成一种新图,让你求最多有多少种无环图. 析:假设这个图中没有环,那么有多少种呢?也就是说每一边都有两种放法,一共有2^x种,x是边数,那么如 ...
- CodeForces 711D Directed Roads (DFS找环+组合数)
<题目链接> 题目大意: 给定一个$n$条边,$n$个点的图,每个点只有一条出边(初始状态),现在能够任意对图上的边进行翻转,问你能够使得该有向图不出先环的方案数有多少种. 解题分析: 很 ...
- CodeForces #368 div2 D Persistent Bookcase DFS
题目链接:D Persistent Bookcase 题意:有一个n*m的书架,开始是空的,现在有k种操作: 1 x y 这个位置如果没书,放书. 2 x y 这个位置如果有书,拿走. 3 x 反转这 ...
随机推荐
- Java中String类的方法及说明
String : 字符串类型 一. String sc_sub = new String(c,3,2); // String sb_copy = new String(sb) ...
- C#实现鸽巢排序
/// <summary> /// 鸽巢排序 /// 创建一个长度大于等于待排序数组array元素中最大值的标记数组mark, /// 将数组array中元素值个数映射到mark数组中. ...
- SQL内联多个表
SQL多个表组合成一个表: strSql.Append(@"Select N.NotificationOptionId, S.FullName, No.Title, N.SortCode, ...
- 修改 window.setTimeout,使之可以传递参数和对象参数
/* 功能:修改 window.setTimeout,使之可以传递参数和对象参数 使用方法: setTimeout(回调函数,时间,参数1,,参数n) */ var _setTimeout=setTi ...
- SqlServer Analysis Service的事实维度关系
什么是Fact(事实)维度关系 开发过SSAS Cube的开发人员应该都知道,Cube的维度用法中有一种叫Fact(事实)关系类型,如下图所示: Fact(事实)维度关系就如同上面截图中红框中的描述一 ...
- mysql分区表的原理和优缺点
1.分区表的原理 分区表是由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们也可以直接访问各个分区,存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分 ...
- hash命令
什么是hash ? 在网上找了好久都没找到简截有力的说明.hash 我把它当成是集合,一个hash 就是一个集合,里面字段对应一个元素,元素不重复,字段都不一样. 简单hash 命令 1.hset 哈 ...
- js数组去重方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- netstat命令详解
它主要的用法和详解! (netstat -na 命令),本文主要是说Linux下的netstat工具,然后详细说明一下各种网络连接状态. netstat -nat |awk ‘{print $}’|s ...
- C++开源大全
程序员要站在巨人的肩膀上,C++拥有丰富的开源库,这里包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++ Standard Library:是一系列 ...