codeforces 711D Directed Roads dfs

首先给的每个点只有一个出度既不可能有大于一个出度
每条边可以改变方向
所以每个点最多只能在一个环上,且所有有向环的信息已经给出因为每个点只有一个出度
dfs把每个环都求出来 ans *( 2^n(环的边数) - 2)
最后ans * 2^m(链的边数)

#include
#include
#include
#include
#define maxn 200005
#define mod 1000000007ll
#define LL long long
#include
using namespace std;
vectorve[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;
}

你可能感兴趣的:(dfs)