首页 > 代码库 > Codeforces 711 D. Directed Roads (DFS判环)
Codeforces 711 D. Directed Roads (DFS判环)
题目链接:http://codeforces.com/problemset/problem/711/D
给你一个n个节点n条边的有向图,可以把一条边反向,现在问有多少种方式可以使这个图没有环。
每个连通量必然有一个环,dfs的时候算出连通量中点的个数y,算出连通量的环中点的个数x,所以这个连通量不成环的答案是2^(y - x) * (2^x - 2)。
最后每个连通量的答案相乘即可。
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime>10 #include <list>11 #include <set>12 #include <map>13 using namespace std;14 typedef __int64 LL;15 typedef pair <int, int> P;16 const int N = 2e5 + 5;17 struct Edge {18 int next, to; 19 }edge[N << 1];20 LL mod = 1e9 + 7, d[N], ans, f[N], sum;21 int head[N], cnt;22 bool vis[N];23 24 LL fpow(LL a, LL b) {25 LL res = 1;26 while(b) {27 if(b & 1)28 res = res * a % mod;29 a = a * a % mod;30 b >>= 1;31 }32 return res;33 }34 35 inline void add(int u, int v) {36 edge[cnt].next = head[u];37 edge[cnt].to = v;38 head[u] = cnt++;39 }40 41 void dfs(int u, int p, int dep) {42 if(!ans && vis[u]) {43 ans = dep - d[u] ? dep - d[u] : 2;44 return ;45 } else if(vis[u]) {46 return ;47 }48 d[u] = dep;49 vis[u] = true;50 ++sum;51 for(int i = head[u]; ~i; i = edge[i].next) {52 int v = edge[i].to;53 if(v == p)54 continue;55 dfs(v, u, dep + 1);56 }57 }58 59 int main()60 {61 f[0] = 1;62 for(int i = 1; i < N; ++i) {63 f[i] = f[i - 1]*2LL % mod; //2的阶乘预处理64 }65 memset(head, -1, sizeof(head));66 cnt = 0;67 int n, u;68 scanf("%d", &n);69 for(int i = 1; i <= n; ++i) {70 scanf("%d", &u);71 add(u, i);72 add(i, u);73 }74 LL res = 1;75 for(int i = 1; i <= n; ++i) {76 if(!vis[i]) {77 ans = sum = 0;78 dfs(i, -1, 1);79 res = ((res * (f[ans] - 2) % mod + mod) % mod * f[sum - ans]) % mod;80 }81 }82 printf("%lld\n", res);83 return 0;84 }
Codeforces 711 D. Directed Roads (DFS判环)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。