1

这是来自 Codeforces PC 的问题,可以在此处查看。

你有一个无向图 G,由 n 个节点组成。我们将考虑由从 1 到 n 的整数索引的图的节点。我们知道图 G 的每个节点都通过边与该图的至少 k 个其他节点相连。你的任务是在给定的图中找到一个长度至少为 k + 1 的简单循环。

图 G 中长度为 d (d > 1) 的简单循环是一系列不同的图节点 v1、v2、...、vd,这样节点 v1 和 vd 通过图的边连接,对于任何整数也是如此i (1 ≤ i < d) 节点 vi 和 vi + 1 由图的边连接。输入

第一行包含三个整数 n, m, k (3 ≤ n, m ≤ 105; 2 ≤ k ≤ n - 1)——图的节点数,图的边数和下限图节点的度数。接下来的 m 行包含整数对。第 i 行包含整数 ai, bi (1 ≤ ai, bi ≤ n; ai ≠ bi) — 由第 i 条边连接的图节点的索引。

保证给定的图不包含任何多重边或自环。保证图的每个节点通过边与图的至少 k 个其他节点相连。输出

在第一行打印整数 r (r ≥ k + 1) — 找到的循环的长度。在下一行打印 r 个不同的整数 v1, v2, ..., vr (1 ≤ vi ≤ n) — 找到的简单循环。

可以保证答案存在。如果有多个正确答案,您可以打印其中任何一个。

输入:

3 3 2 1 2 2 3 3 1

输出:

3 1 2 3

我的方法:

我使用了 DFS,但超出了时间限制(TLE)。不知道如何快速做到这一点。

4

1 回答 1

2

我认为如果您确保搜索永远不会回溯,则使用每个节点的邻居列表的 DFS 应该满足时间限制。

DFS的基本思想是访问任何尚未访问过的节点并进行递归。

一旦我们到达一个节点 x,我们就不能递归了,比如说,它的所有邻居都已经被访问过。由于问题陈述,它必须至少有 k 个邻居。

通过返回最先遇到的邻居节点,形成一个长度为 k+1 的循环。

我们可以通过将访问节点的递归深度存储在数组中来轻松确定首先遇到哪个节点。

解释

假设我们已经到达节点 x,其邻居 a、b、c、d 都已经被访问过。

这意味着我们必须找到一条看起来像这样的路径:

开始->...->a->..->b->..->c->..->d->..->x

所以通过从 x 到 a 的循环,我们有一个至少长度为 k+1 的循环。(k 因为我们有 k 个邻居 a,b,c,d 和 +1 因为我们还包括节点 x。)

于 2013-01-16T20:01:12.727 回答