DFS -检查周期
DFS - Checking Cycles
目的是找出一个无向的、未加权的图是否是树,即检查它是否包含后边。我正在使用一种修改形式的白-灰-黑DFS算法(这是在Cormen和这里提到的说明:http://www.cs.cornell.edu/~wdtseng/icpc/notes/graph_part1.pdf)
但不知何故,它不起作用。它工作了一次,但在SPOJ (http://www.spoj.com/problems/PT07Y/)导致运行时错误。
更新:我现在得到了这个问题的错误答案。但是,代码适用于示例测试用例。
失败测试用例:
10 9
1 2
2 3
3 4
4 5
5 6
6 4
6 7
7 8
8 9
#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <vector>
#include <cstdlib>
using namespace std;
bool M[10001][10001] = { 0 } ;
int color[10001] = { 0 };
long long int n;
bool answer=false;
void condition()
{
cout<<"NO"<<endl;
exit(0);
}
void condition2()
{
cout<<"YES"<<endl;
exit(0);
}
void dfs(int u, int p)
{
color[u] = 1;
for(int v=0; v < n; v++)
{
if(M[u][v] && v != p)
{
if (color[v] == 0)
dfs(v, u);
else if (color[v]==1)
{
condition(); /* It has a backedge so it is not a tree, so print No */
}
}
}
condition2(); /* It does not have backedge so it is not a tree so print YES */
}
int main()
{
long Z;
cin>>n>>Z;
// for(int i=0; i<n; i++) /* **Removed THIS nested loop to reduce runtime, successfully eliminated TLE** */
// for(int j=0; j<n;j++)
// M[i][j]=0;
for(int i=0; i < Z; i++)
{
long temp1, temp2;
cin>>temp1;
cin>>temp2;
temp1--;
temp2--;
M[temp1][temp2]=1;
M[temp2][temp1]=1;
}
if(Z==n-1)
dfs(0, -1);
else cout<<"NO"<<endl;
return 0;
}
如果图是连通的且E = V-1
,则图是树,其中E
和V
分别是边数和节点数。因此,只要在启动DFS之前检查E==V-1
,您应该能够在O(V)
时间内解决它。
你能测试你的程序对一个图,这是一个路径与20000
节点,节点编号0
是一个叶子,有一个边从i
到i+1
?请尝试在堆栈大小限制设置为SPOJ(8MB IIRC)的情况下运行它,并确保没有堆栈溢出。这是堆栈使用情况的最坏情况图。如果您确实看到递归太深,则可以使用BFS
来检查连接组件的数量是否为1。或者,您可以使用路径压缩,这将使您的运行时O(n log n)
,但仍然容易快到足以满足1秒的限制。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- 检查输入是否不是整数或数字
- 试图让变量检查数组中的某些内容
- 检查值是否在集合p1和p2中,但不在p3中
- C++概念:如何使用'concept'检查模板化结构的属性?
- 概念TS检查忽略私有访问修饰符
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何在C++中检查2D数组中负值的输入验证
- C++:正在检查LinkedList中的回文-递归方法-错误
- 使用for循环检查数组中的重复项
- 如何检查一个c++字符串中有多少相同的字符/数字
- 检查不带转换的扫描格式
- 如何检查线程是否锁定
- 清除前检查矢量
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- C++LDAP检查用户是否是特定组的成员
- 编译时生命周期检查
- DFS -检查周期