2021-1 有向图 寻找有向环 c++实现

DirectedCycle API

  • DirectedCycle(Digraph G) 寻找有向环的构造函数
  • bool hasCycle() G中是否含有有向环
  • stack<int> cycle() 有向环中的所有顶点(如果存在的话)

图解

在这里插入图片描述

代码

#pragma once
#include<stack>
#include"Digraph.h"
class DirectedCycle
{
    
    
public:
	DirectedCycle(Digraph& G);

	bool hasCycle() {
    
    
		return m_cycle != nullptr;
	}

	stack<int>* cycle() {
    
    
		return m_cycle;
	}
	
private:
	vector<bool>* m_marked = nullptr;//标记数组
	vector<int>* m_father = nullptr;//记录父节点
	vector<bool>* m_onStack = nullptr;//是否在栈内
	stack<int>* m_cycle = nullptr;//记录环

	void dfs(Digraph& G, int v);
};

void testDirectedCycle();
#include "DirectedCycle.h"

DirectedCycle::DirectedCycle(Digraph& G)
{
    
    
	int n = G.V();
	m_marked = new vector<bool>(n, false);
	m_father = new vector<int>(n, -1);
	m_onStack = new vector<bool>(n, false);

	for (int i = 0; i < n; ++i) {
    
    
		if (!m_marked->at(i)) {
    
    
			dfs(G, i);
		}
	}
}

void DirectedCycle::dfs(Digraph& G, int v)
{
    
    
	m_onStack->at(v) = true;//入栈标记
	m_marked->at(v) = true;

	forIt(G.adj(v)) {
    
    
		if(this->hasCycle()) return;
		if(!m_marked->at(*it)) {
    
    //孩子未被标记,继续叠罗汉
			m_father->at(*it) = v;
			dfs(G, *it);
		}else if(m_onStack->at(*it)){
    
    //已被标记,且还在栈里,必然有环
			m_cycle = new stack<int>();
			for (int i = v; i != *it; i=m_father->at(i)) {
    
    
				m_cycle->push(i);
			}
			m_cycle->push(*it);
			m_cycle->push(v);
		}
	}
	m_onStack->at(v) = false;
}

void testDirectedCycle()
{
    
    
	Digraph G("tinyDG.txt");
	DirectedCycle DC(G);
	out(DC.hasCycle()),hh;

	Digraph G1("tinyDAG.txt");
	DirectedCycle DC2(G1);
	out(DC2.hasCycle()), hh;
}

头文件 Digraph.h

tinyDAG.txt

13
15
2 3 
0 6 
0 1 
2 0 
11 12  
9 12  
9 10  
9 11 
3 5 
8 7 
5 4 
0 5 
6 4 
6 9 
7 6

猜你喜欢

转载自blog.csdn.net/qq_34890856/article/details/113002307