2021-1 判断无向图是否有环 与 判断一个图是否是二分图 c++

构建图的头文件见 Graph.h

判断是否有环

采用dfs搜索,维护三个顶点信息,【上一个已访问节点,当前节点,下一个】。直接的,当【下一个】已经被标记且不是【上一个】,说明有环。因为,被标记节点【上一个】,【下一个】属于一个联通子图,即有路径相连。

Cycle.h

#pragma once
#include"Graph.h"
class Cycle
{
    
    
private:
	vector<int>* m_visited = nullptr;
	bool m_hasCycle = false;
	void dfs(Graph& G, int now, int pre);
public:
	Cycle() {
    
    }
	Cycle(Graph& G);

	bool hasCycle() {
    
     return m_hasCycle; }
};


void Cycle::dfs(Graph& G, int now, int pre)
{
    
    
	m_visited->at(now) = 1;
	for (auto next : G.adj(now) ) {
    
    
		
		if (!m_visited->at(next)) {
    
    
			dfs(G, next, now);
		}
		else if (next != pre) {
    
    
			m_hasCycle = true;
		}
	}
}

Cycle::Cycle(Graph& G)
{
    
    
	int n = G.V();
	m_visited = new vector<int>(n, 0);
	for (int i = 0; i < n; i++) {
    
    
		if (!m_visited->at(i)) {
    
    
			dfs(G, i, i);
		}
	}
}

void testCycle()
{
    
    
	Graph G("data.txt");
	Cycle cle(G);
	printf_s("has cycle ? "), cout<<(cle.hasCycle())<<endl;
}

二分图问题

用两种颜色上色,并且保证相同颜色的节点不相邻,能这样上色的就是二分图。例如,演员和电影的关系图,电影电影之间要通过演员连接。

方法:用dfs搜索,保证【now,next】颜色不同。当出现【now】和【next】都已经标记,且同色,涂色失败,即不可能是二分图。

TwoColor.h

#pragma once
#include"Graph.h"
class TwoColor
{
    
    
private:
	vector<bool>* m_visited = nullptr;
	vector<bool>* m_color = nullptr;
	bool m_isTwoColorable = true;

	void dfs(Graph& G, int v);
public:
	TwoColor() {
    
    }
	TwoColor(Graph& G);

	bool isBipartite() {
    
    
		return m_isTwoColorable;
	}
};

void TwoColor::dfs(Graph& G, int v)
{
    
    
	m_visited->at(v) = true;

	for (auto& next : G.adj(v)) {
    
    
		if (!m_visited->at(next)) {
    
    
			m_color->at(next) = !m_color->at(v);
			dfs(G, next);
		}//孩子已经标记且和父亲同色
		else if (m_color->at(next) == m_color->at(v)) {
    
    
			m_isTwoColorable = false;
		}
	}

}

TwoColor::TwoColor(Graph& G)
{
    
    
	m_visited = new vector<bool>(G.V(), false);
	m_color = new vector<bool>(G.V(), false);

	for (int i = 0; i < G.V(); ++i) {
    
    
	//遍历所有节点去涂色
		if (!m_visited->at(i)) {
    
    
			dfs(G, i);
		}
	}
}

//测试当前的类
void testTwoColor()
{
    
    
	Graph G("data.txt");
	TwoColor two(G);
	cout << (two.isBipartite()) << endl;

}

data.txt

6
6
1 3
3 5
1 4
4 5
2 4
0 5

猜你喜欢

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