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;
}


相关文章
|
数据安全/隐私保护 Docker 容器
minio
minio
669 0
|
编解码 前端开发 JavaScript
11.使用HTML制作滑动广告
11.使用HTML制作滑动广告
333 0
|
存储 弹性计算 运维
判断用户输入的数据类型
【4月更文挑战第29天】
96 0
|
编译器 C语言 C++
初始C语言——梦开始的地方
C语言是一门通用计算机编程语言,广泛应用于底层开发。作为长期位于各大编程语言排行榜前三的高级语言,C语言具有广泛性、简洁性、结构完善性等特有特点,作为B语言的改进版本,C语言也能直接通过内存地址进行内存操作,这是大多数高级语言所不具备的特点,而我们的C可以。因此C语言具有极为强大的功能和较为直接的底层逻辑,换句话说,只要把C学好了,就能掌握编程的核心技术,其他高级语言的学习如探囊取物。
357 0
初始C语言——梦开始的地方
|
SQL 关系型数据库 MySQL
mysql 1449 : The user specified as a definer (‘root‘@‘%‘) does not exist 解决方法
mysql 1449 : The user specified as a definer (‘root‘@‘%‘) does not exist 解决方法
308 0
mysql 1449 : The user specified as a definer (‘root‘@‘%‘) does not exist 解决方法
|
算法 Python
数据结构|字符串匹配
数据结构|字符串匹配
163 0
|
存储
链式存储之:链表的引出及其简介
链式存储之:链表的引出及其简介
186 0
链式存储之:链表的引出及其简介
|
C语言
【数据结构】C语言版本的带哨兵位双向循环链表的快速实现方法
我们在之前学双向带头循环链表时,结尾部分简单讲解了快速实现的方法。本篇博客将详细讲解如何迅速实现,通过思路草图的方法轻松写出带头双向循环链表,甚至都可以直接用注释画草图。本篇博客是对 "从零开始逐步实现带哨兵位循环双向链表" 的补充,之前在写那篇博客的时候不小心忘记实现销毁接口了,这里正好能进行一个补充。
296 0
【数据结构】C语言版本的带哨兵位双向循环链表的快速实现方法
|
存储 算法 开发者
数据结构和算法_栈的出栈操作|学习笔记
快速学习数据结构和算法_栈的出栈操作
321 0
数据结构和算法_栈的出栈操作|学习笔记
|
Python
matplotlib的基本图表配置之plot的使用(三)
matplotlib的基本图表配置之plot的使用
199 0
matplotlib的基本图表配置之plot的使用(三)