Typesetting math: 100%
长存不灭的过去|

xixike

园龄:5年粉丝:40关注:20

2021-11-02 07:37阅读: 82评论: 4推荐: 0

CF711D Directed Roads 题解

Description

洛谷传送门

Solution

看到 nn 个点 nn 条边,显然的基环树(可能是基环树森林),所以我们对于环上的点和非环上的点分别处理。

假设一共有 cntcnt 个环,每个环上有 didi 个点,我们来分类讨论一下:

  • 对于环上的点,我们发现只有两种情况会产生环,即

    • 123···di1di1123di1di1
    • didi1···321dididi1321di

    所以我们用总情况数减去 22即可。方案数:

    ans=cnti=1(2di2)ans=cnti=1(2di2)

  • 对于非环上的点,我们发现不论朝哪个方向连,都不会影响是否会产生环,所以方案数为 22

    ans=2ncnti=1dians=2ncnti=1di

至此,我们就讨论完了(事实上还是很简单的),总结一下:

ans=cnti=1(2di2)×2ncnti=1dians=cnti=1(2di2)×2ncnti=1di

那么如何找环呢?我这里写了个 Tarjan 缩点,大小大于 2 的强连通分量就是环(感觉用牛刀杀鸡了……不管了)。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long

using namespace std;

const ll mod = 1e9 + 7;
const ll N = 2e5 + 10;
ll n;
struct node{
    ll v, nxt;
}edge[N];
ll head[N], tot;
ll dfn[N], low[N], tim;
ll stk[N], top, t[N];
ll cnt, siz[N];

inline void add(ll x, ll y){
    edge[++tot] = (node){y, head[x]};
    head[x] = tot;
}

void tarjan(ll x){
    low[x] = dfn[x] = ++tim;
    stk[++top] = x;
    t[x] = 1;
    for(ll i = head[x]; i; i = edge[i].nxt){
        ll y = edge[i].v;
        if(!dfn[y])tarjan(y), low[x] = min(low[x], low[y]);
        else if(t[y]) low[x] = min(low[x], dfn[y]);
    }
    if(low[x] == dfn[x]){
        cnt++;
        do{
            siz[cnt]++;
            t[stk[top--]] = 0;
        }while(stk[top + 1] != x);
    }
}

inline ll qpow(ll a, ll b){
    ll res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

signed main(){
    scanf("%lld", &n);
    for(ll i = 1, x; i <= n; ++i){
        scanf("%lld", &x);
        add(i, x);
    }
    for(ll i = 1; i <= n; ++i)
        if(!dfn[i]) tarjan(i);
    ll sum = 0, ans = 1;
    for(ll i = 1; i <= cnt; ++i)
        if(siz[i] > 1) ans = ans * (qpow(2, siz[i]) - 2 + mod % mod) % mod, sum += siz[i];
    ans = ans * qpow(2, n - sum) % mod;
    printf("%lld\n", ans);
    return 0;
}

_EOF__EOF_

本文作者:xixike

本文链接:https://www.cnblogs.com/xixike/p/15497096.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xixike  阅读(82)  评论(4编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起