以下是一个简单的 C++ 程序,用于构建一个有向无环图(DAG)的拓扑结构,并验证是否可以正确进行拓扑排序。这个程序使用深度优先搜索 (DFS) 方法来检测环,并使用 Kahn 算法来进行拓扑排序。如果图中存在环,则拓扑排序无效。
拓扑图构建和验证程序
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
class Graph {
private:
int vertices; // 顶点数量
vector<vector<int>> adjList; // 邻接表
vector<int> inDegree; // 入度表
public:
// 构造函数
Graph(int v) : vertices(v), adjList(v), inDegree(v, 0) {}
// 添加边
void addEdge(int u, int v) {
adjList[u].push_back(v);
inDegree[v]++; // 更新入度
}
// 检查是否有环
bool hasCycle() {
vector<int> tempInDegree = inDegree; // 拷贝入度表
queue<int> q;
// 将所有入度为 0 的节点加入队列
for (int i = 0; i < vertices; ++i) {
if (tempInDegree[i] == 0) {
q.push(i);
}
}
int count = 0; // 记录已排序的节点数
while (!q.empty()) {
int node = q.front();
q.pop();
count++;
// 遍历相邻节点并减少入度
for (int neighbor : adjList[node]) {
if (--tempInDegree[neighbor] == 0) {
q.push(neighbor);
}
}
}
// 如果排序节点数等于图的顶点数,则无环;否则有环
return count != vertices;
}
// 执行拓扑排序
vector<int> topologicalSort() {
vector<int> result;
if (hasCycle()) {
cout << "Graph contains a cycle. Topological sorting is not possible." << endl;
return result; // 返回空结果
}
vector<int> tempInDegree = inDegree; // 使用临时入度表
queue<int> q;
// 将入度为 0 的节点加入队列
for (int i = 0; i < vertices; ++i) {
if (tempInDegree[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int node = q.front();
q.pop();
result.push_back(node);
// 减少相邻节点的入度
for (int neighbor : adjList[node]) {
if (--tempInDegree[neighbor] == 0) {
q.push(neighbor);
}
}
}
return result;
}
// 打印拓扑排序结果
void printTopologicalSort() {
vector<int> sortedOrder = topologicalSort();
if (!sortedOrder.empty()) {
cout << "Topological Sort: ";
for (int node : sortedOrder) {
cout << node << " ";
}
cout << endl;
}
}
};
int main() {
int vertices, edges;
cout << "Enter the number of vertices: ";
cin >> vertices;
cout << "Enter the number of edges: ";
cin >> edges;
Graph graph(vertices);
cout << "Enter the edges (u v):" << endl;
for (int i = 0; i < edges; ++i) {
int u, v;
cin >> u >> v;
graph.addEdge(u, v);
}
// 验证是否有环并打印拓扑排序
graph.printTopologicalSort();
return 0;
}
程序说明
- Graph 类:包含图的结构和操作方法。
- addEdge(int u, int v):用于添加有向边 。
- hasCycle():用于检测图中是否有环,通过 BFS 来检查是否所有节点都能被拓扑排序。
- topologicalSort():使用 Kahn 算法实现拓扑排序,返回排序后的节点顺序。
- printTopologicalSort():打印拓扑排序结果,如果有环则提示拓扑排序不可行。
- 输入和输出:
- 程序首先接受顶点数和边数的输入。
- 接着输入每条边的起点和终点。
- 最后输出拓扑排序结果,如果图中有环则输出相关信息。
示例运行
Enter the number of vertices: 6
Enter the number of edges: 6
Enter the edges (u v):
5 2
5 0
4 0
4 1
2 3
3 1
Topological Sort: 4 5 2 3 1 0
111
在该示例中,程序构建了一个有向无环图并输出了顶点的拓扑排序。