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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值