1. 程式人生 > >codeforces 711D Directed Roads dfs

codeforces 711D Directed Roads dfs

首先給的每個點只有一個出度既不可能有大於一個出度
每條邊可以改變方向
所以每個點最多隻能在一個環上,且所有有向環的資訊已經給出因為每個點只有一個出度
dfs把每個環都求出來 ans *( 2^n(環的邊數) - 2)
最後ans * 2^m(鏈的邊數)

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<map>
#define maxn 200005
#define mod 1000000007ll
#define LL long long
#include<vector>
using namespace std; vector<LL>ve[maxn]; int sym[maxn], sym2[maxn]; int siz[maxn]; LL n, ans = 1; LL fastMod(LL n) { LL ans = 1, pre = 2; while(n) { if(n & 1ll)ans *= pre; pre *= pre; pre %= mod; ans %= mod; n >>= 1ll; } return ans; } void
dfs(LL pre, LL sum) { sym[pre] = 1; sym2[pre] = 1; siz[pre] = sum; for(int i = 0; i < ve[pre].size(); i++) { if(sym[ve[pre][i]]) { if(sym2[ve[pre][i]] == 1) { ans *= ((fastMod(siz[pre] - siz[ve[pre][i]] + 1) - 2) % mod + mod) % mod; ans %= mod; n -= siz[pre] - siz[ve[pre][i]] + 1
; } } else dfs(ve[pre][i], sum + 1); } sym2[pre] = 0; } int main() { scanf("%I64d", &n); for(int i = 1; i <= n; i++) { LL pre; scanf("%I64d", &pre); ve[i].push_back(pre); } LL n1 = n; for(int i = 1; i <= n1; i++) if(!sym[i]) dfs(i, 1); ans *= fastMod(n); ans %= mod; printf("%I64d\n", ans); return 0; }