循环图表

时间:2013-01-16 19:25:14

标签: algorithm

这是来自Codeforces PC的问题,可以查看here

  

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

     

图G中的长度d(d> 1)的简单循环是序列   不同的图节点v1,v2,...,vd等,节点v1和vd是   通过图的边缘连接,也用于任何整数i(1≤i      

第一行包含三个整数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)。不知道如何快速做到这一点。

1 个答案:

答案 0 :(得分: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。)