D. Directed Roads(拓扑排序+组合计算)

简介: D. Directed Roads(拓扑排序+组合计算)

D. Directed Roads

思路

  • 环外的边可以随意变换,每个环上的的贡献是2环的大小−22^{环的大小} - 22环的大小2,相乘就是答案
  • 在写代码发现构建了无向图,有点问题,记录一下

可以发现,做完拓扑有很多点的度数是负数,才发现无向图的拓扑排序后,度数 < 1 的点都是环外的点

总之,很有必要记录一下无向图的拓扑排序

代码

cpp

复制代码

const int N = 2e5 + 10, mod = 1e9 + 7;
vector<int> edge[N];
int d[N];
int fa[N];
int siz[N];
int find(int u)
{
    if (fa[u] != u)
        fa[u] = find(fa[u]);
    return fa[u];
}
int qmi(int x, int y)
{
    int res = 1;
    while (y)
    {
        if (y & 1)
            res = (1LL * res * x) % mod;
        x = (1LL * x * x) % mod;
        y >>= 1;
    }
    return res;
}
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        fa[i] = i, siz[i] = 1;
    for (int i = 1; i <= n; i++)
    {
        int u;cin >> u;
        edge[u].push_back(i);edge[i].push_back(u);
        d[u]++;d[i]++;
    }
    int cir_out = 0;
    queue<int> q;
    for (int i = 1; i <= n; i++)if (d[i] == 1)q.push(i);
    while (q.size())
    {
        int u = q.front();q.pop();
        cir_out++;
        for (auto v : edge[u])
        {
            d[u]--;d[v]--;
            if (d[v] == 1)
                q.push(v);
        }
    }
    for (int u = 1; u <= n; u++)
    {
        if (d[u] < 1)continue;
        for (auto v : edge[u])
        {
            if (d[v] < 1)continue;
            int pu = find(u), pv = find(v);
            if (pu != pv)
            {
                siz[pv] += siz[pu];
                fa[pu] = pv;
            }
        }
    }
    LL ans = qmi(2, cir_out);
    for (int u = 1; u <= n; u++)
    {
        if (find(u) == u && siz[u] > 1)
        {
            ans = (ans * ((qmi(2, siz[u]) - 2 + mod) % mod)) % mod;
        }
    }
    cout << ans << endl;
}


相关文章
|
存储 算法 搜索推荐
拓扑排序:求取拓扑序列
拓扑排序简单讲就是在可求拓扑序列的有向无回路图(有向无环图)中求取拓扑序列的排序算法。通俗讲就是按活动的先后次序进行排序的序列,并且每一个顶点只出现一次,它可以表述出完成某一项活动所需要的前置活动
79 0
拓扑排序:求取拓扑序列
【矩阵分析】矩阵幂级数 发散 条件 || 幂级数 与 解析函数 的关系 || 幂级数 收敛半径r 的求法
【矩阵分析】矩阵幂级数 发散 条件 || 幂级数 与 解析函数 的关系 || 幂级数 收敛半径r 的求法
【矩阵分析】矩阵幂级数 发散 条件 || 幂级数 与 解析函数 的关系 || 幂级数 收敛半径r 的求法
SP10707 COT2 - Count on a tree II(欧拉序 树上莫队)
SP10707 COT2 - Count on a tree II(欧拉序 树上莫队)
115 0
SP10707 COT2 - Count on a tree II(欧拉序 树上莫队)
|
Python
【欧拉计划第 8 题】序列中最大的乘积 Largest product in a series
【欧拉计划第 8 题】序列中最大的乘积 Largest product in a series
124 0
【欧拉计划第 8 题】序列中最大的乘积 Largest product in a series
【CCCC】L3-006 迎风一刀斩 (30分),几何关系,找规律 (拼合多边形==斜边等价)
【CCCC】L3-006 迎风一刀斩 (30分),几何关系,找规律 (拼合多边形==斜边等价)
159 0
POJ1269 Intersecting Lines(两直线关系)
POJ1269 Intersecting Lines(两直线关系)
61 0
UPC Graph (最小生成树 || 并查集+二分)
UPC Graph (最小生成树 || 并查集+二分)
92 0
|
自然语言处理 算法 Java
Levenshtein Distance(编辑距离)算法与使用场景
已经很久没深入研究过算法相关的东西,毕竟日常少用,就算死记硬背也是没有实施场景导致容易淡忘。最近在做一个「脱敏数据和明文数据匹配」的需求的时候,用到了一个算法叫Levenshtein Distance Algorithm,本文对此算法原理做简单的分析,并且用此算法解决几个常见的场景。
452 0
Levenshtein Distance(编辑距离)算法与使用场景
|
机器学习/深度学习 算法
卡特兰数(Catalan Number) 算法、数论 组合~
卡特兰数(Catalan Number) 算法、数论 组合~
226 0
卡特兰数(Catalan Number) 算法、数论 组合~
[USACO | UPC] Liars and Truth Tellers | 拓展域并查集
题目描述 After spending so much time around his cows, Farmer John has started to understand their language. Moreover, he notices that among his N cows (2 ≤ N ≤ 1000 ), some always tell the truth while others always lie.
127 0