博客
关于我
2019秦皇岛CCPC F.Forest Program(DFS找环)
阅读量:747 次
发布时间:2019-03-22

本文共 1593 字,大约阅读时间需要 5 分钟。

关于将图变成森林的思路与实现

在图论中,我们常常需要对图进行编辑,使其满足特定条件。本文将重点讨论如何通过删除图中的边,将一个无向图转换成一片森林。具体来说,我们需要确保删除后的图中每个连通块都是一棵树,即无环且没有自环。

分析与思路

首先,需要理解原图的结构特点。假设给定的图是无向图,满足以下条件:

  • 没有多重边。
  • 存在至少一个简单环。
  • 没有自环。

我们的目标是通过删除一些边,使该图变为一片森林。为此,我们需要解决如何处理环状结构,以及如何管理非环边。

每个环都需要至少删除一条边才能消除环。因此,对于一个环,边的数量为c,我们至少需要删除c条边中的一条。这个问题类似于集合论中的反馈问题,因此贡献为2^c - 1。这是因为对于c条边中的每一条都可能被删除,剩下的边最多可以保留c条。

对于非环边,也就是不属于任何环的边,它们的删除或保留都不会影响是否形成一个森林。对于这些边,每一条都有两种选择:保留或删除。因此,贡献为2^num,其中num是非环边的总数。

针对图的具体处理

  • 环的识别与处理

    要有效地处理环,我们可以使用DFS(深度优先搜索)来遍历图。每当我们从一个未访问的节点开始遍历时,递增计数器记录所经历的环的数量。

  • 边分类与计算

    • 环上的边:每个环至少需要删除一条边。对于每个环,假设边数量为c,贡献为2^c - 1。
    • 非环边:对于非环边,假设总数为num,每条边可以保留或删除,贡献为2^num。
  • 数学计算

    总贡献为:2^(m - cnt) * (2^cnt - 1),其中m是总边数,cnt是环边的总数(注意:这里的cnt应根据环的数量和每个环的边数动态计算)。

  • 实现细节

    进行DFS时,可以维护一个计数器记录当前访问层数。如果在某一步返回时发现当前节点已经被访问过,但不是通过父节点访问的,就表示这里存在环。我们需要记录所有环的数量。

  • 代码实现

    以下是使用C++语言实现该思路的代码框架:

    #include 
    #include
    using namespace std;typedef long long ll;const int N = 1e6 + 5;const ll mod = 998244353;vector
    e[N]; // 边的邻接表int vis[N]; // 记录访问状态ll ans;int n, m, num; // n为节点数,m为边数,num为非环边数ll qpow(ll a, ll b) { ll res = 1; a %= mod; while (b > 0) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res;}void dfs(int now, int x, int f) { vis[x] = now; for (int it : e[x]) { if (it == f) continue; if (!vis[it]) { dfs(now + 1, it, x); } else if (vis[it] < now) { // 表示环存在 // 递增cnt cnt++; } }}

    总结

    将图转换成森林的关键在于处理环的边以及非环边。通过DFS遍历图,识别环并统计环的数量。对于每个环,至少删除一条边,贡献为2^c - 1。对于非环边,每条边可以选择保留或删除,贡献为2^num。最终的答案可以通过合并这些贡献计算得出。

    转载地址:http://luhwk.baihongyu.com/

    你可能感兴趣的文章
    MySQL 数据库备份种类以及常用备份工具汇总
    查看>>
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>
    MySQL 数据库设计总结
    查看>>
    Mysql 数据库重置ID排序
    查看>>
    Mysql 数据类型一日期
    查看>>
    MySQL 数据类型和属性
    查看>>
    mysql 敲错命令 想取消怎么办?
    查看>>
    Mysql 整形列的字节与存储范围
    查看>>
    mysql 断电数据损坏,无法启动
    查看>>
    MySQL 日期时间类型的选择
    查看>>
    Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
    查看>>
    MySQL 是如何加锁的?
    查看>>
    MySQL 是怎样运行的 - InnoDB数据页结构
    查看>>
    mysql 更新子表_mysql 在update中实现子查询的方式
    查看>>
    MySQL 有什么优点?
    查看>>
    mysql 权限整理记录
    查看>>
    mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
    查看>>
    MYSQL 查看最大连接数和修改最大连接数
    查看>>