给定一个有N个顶点和M 条边的有向图,其中可能包含环,任务是找到该图的字典序最小拓扑排序,如果它存在,否则打印-1 (如果图有环)。
字典序最小的拓扑排序意味着如果图中的两个顶点没有任何传入边,那么编号较小的顶点应首先出现在排序中。
例如,在下图中,许多拓扑排序是可能的,例如5 2 3 4 0 1, 5 0 2 4 3 1 。
但最小的顺序是4 5 0 2 3 1 。
例子:
Input:
Output: 4 5 0 2 3 1
Even though 5 4 0 2 3 1 is also a valid topological
ordering of the given graph but it is not
lexicographically smallest.
方法:我们将使用 Kahn 的拓扑排序算法进行修改。我们将使用多重集来存储顶点,而不是使用队列,以确保每次我们选择一个顶点时,它都是可能的最小顶点。整体时间复杂度变为
下面是上述方法的实现:
CPP
// C++ implementation of the approach
#include
using namespace std;
// Class to represent a graph
class Graph {
int V; // No. of vertices'
// Pointer to an array containing
// adjacency listsList
list* adj;
public:
Graph(int V); // Constructor
// Function to add an edge to graph
void addEdge(int u, int v);
// Function to print the required topological
// sort of the given graph
void topologicalSort();
};
// Constructor
Graph::Graph(int V)
{
this->V = V;
adj = new list[V];
}
// Function to add an edge to the graph
void Graph::addEdge(int u, int v)
{
adj[u].push_back(v);
}
// Function to print the required topological
// sort of the given graph
void Graph::topologicalSort()
{
// Create a vector to store indegrees of all
// the vertices
// Initialize all indegrees to 0
vector in_degree(V, 0);
// Traverse adjacency lists to fill indegrees of
// vertices
// This step takes O(V+E) time
for (int u = 0; u < V; u++) {
list::iterator itr;
for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
in_degree[*itr]++;
}
// Create a set and inserting all vertices with
// indegree 0
multiset s;
for (int i = 0; i < V; i++)
if (in_degree[i] == 0)
s.insert(i);
// Initialize count of visited vertices
int cnt = 0;
// Create a vector to store result (A topological
// ordering of the vertices)
vector top_order;
// One by one erase vertices from setand insert
// adjacents if indegree of adjacent becomes 0
while (!s.empty()) {
// Extract vertex with minimum number from multiset
// and add it to topological order
int u = *s.begin();
s.erase(s.begin());
top_order.push_back(u);
// Iterate through all its neighbouring nodes
// of erased node u and decrease their in-degree
// by 1
list::iterator itr;
for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
// If in-degree becomes zero, add it to queue
if (--in_degree[*itr] == 0)
s.insert(*itr);
cnt++;
}
// Check if there was a cycle
if (cnt != V) {
cout << -1;
return;
}
// Print topological order
for (int i = 0; i < top_order.size(); i++)
cout << top_order[i] << " ";
}
// Driver code
int main()
{
// Create the graph
Graph g(6);
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);
// Find the required topological order
g.topologicalSort();
return 0;
}
输出:
4 5 0 2 3 1
时间复杂度: O(N)
辅助空间: O(N)