Bootstrap

判断有向图是否存在环(DFS/拓扑排序)

方法一:DFS

template<class verType, class edgeType>
bool Graph<verType, edgeType>::circleJudge() const {
    vector<bool> visited(verts, false); // 跟踪节点是否被访问过
    vector<bool> recStack(verts, false); // 跟踪递归栈

    for (int i = 0; i < verts; ++i) {
        if (!visited[i]) // 如果节点未被访问过
            if (isCyclicUtil(i, visited, recStack)) // 调用工具函数
                return true;
    }
    return false;
}

template<class verType, class edgeType>
bool Graph<verType, edgeType>::isCyclicUtil(int v, vector<bool>& visited, vector<bool>& recStack) const {
    if (!visited[v]) {
        visited[v] = true; // 标记当前节点为已访问
        recStack[v] = true; // 加入递归栈
        
        // 遍历所有邻接点
        for (int j = 0; j < verts; ++j) {
            if (edgeMatrix[v][j] != noEdge) { // 如果存在边
                if (!visited[j] && isCyclicUtil(j, visited, recStack)) // 递归访问邻接点
                    return true;
                else if (recStack[j]) // 如果邻接点在递归栈中,存在环
                    return true;
            }
        }
    }
    recStack[v] = false; // 移除当前节点出递归栈
    return false;
}

方法二:拓扑排序

template<class verType, class edgeType>
bool Graph<verType, edgeType>::circleJudge() const {
    //计算所有结点的入度
	bool InList[Vers];
	for (int i = 0; i < Vers; i++)
	{
		InList[i] = false;
	}
	int InDegree[Vers];
	for (int i = 0; i < Vers; i++){
		for (int j = 0; j < Vers; j++){
			if (edgeMatrix[i][j] != NoEdge) InDegree[j]++;
		}
	}
	queue<int> q;
	for (int i = 0; i < Vers; i++){
		if (InDegree[i] == 0)  q.push(i); //入度为0的结点入队
	}
	while (!q.empty())
	{
		int tmp = q.front();
		q.pop();
		Inlist[tmp] = true;
		for (int k = 0; k < Vers; k++){
			if (edgeMatrix[tmp][k] != NoEdge) {
				if (--InDegree[k] == 0)
					q.push(k);
			}
		}
	}
	for (int i = 0; i < Vers; i++)
		if (InList[i] == false) return true;
	return false;
	

}

;