博客
关于我
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 内连接、自然连接、外连接的区别
    查看>>
    mysql 写入慢优化
    查看>>
    mysql 分组统计SQL语句
    查看>>
    Mysql 分页
    查看>>
    Mysql 分页语句 Limit原理
    查看>>
    MySql 创建函数 Error Code : 1418
    查看>>
    MySQL 创建新用户及授予权限的完整流程
    查看>>
    mysql 创建表,不能包含关键字values 以及 表id自增问题
    查看>>
    mysql 删除日志文件详解
    查看>>
    mysql 判断表字段是否存在,然后修改
    查看>>
    MySQL 到底能不能放到 Docker 里跑?
    查看>>
    mysql 前缀索引 命令_11 | Mysql怎么给字符串字段加索引?
    查看>>
    mysql 协议的退出命令包及解析
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    mysql 四种存储引擎
    查看>>
    MySQL 基础模块的面试题总结
    查看>>
    MySQL 备份 Xtrabackup
    查看>>
    mysql 多个表关联查询查询时间长的问题
    查看>>