如何确定图是否具有非唯一拓扑排序
How to determine if a graph has a non-unique topological sort
我创建了一个程序,在给定图表的情况下按拓扑排序组织图表。我确定了 3 个结果:
- 还行
- 现有周期
- 缺少信息
前两点的输出是正确的,但第三点不正确。例如对于有 4 个顶点和边的图:1->2; 3->1; 3->4; 4->2,我得到的结果是:3 1 4 2...错了!已知的不足以得出结论。
感谢任何提示或帮助,提前致谢。
#include<bits/stdc++.h>
using namespace std;
class Graph{
int V;
list<int> *adj;
public:
Graph(int V);
void addEdge(int u, int v);
void topologicalSort();
};
Graph::Graph(int V){
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int u, int v){
adj[u].push_back(v);
}
void Graph::topologicalSort(){
vector<int> in_degree(V, 0);
for (int u=0; u<V; u++){
list<int>::iterator itr;
for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
in_degree[*itr]++;}
queue<int> q;
for (int i = 0; i < V; i++)
if (in_degree[i] == 0)
q.push(i);
int cnt = 0;
vector <int> top_order;
while (!q.empty()){
int u = q.front();
q.pop();
top_order.push_back(u);
list<int>::iterator itr;
for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
if (--in_degree[*itr] == 0)
q.push(*itr);
cnt++;}
if (cnt != V){
cout << "Existing cycle\n";
return;}
for (int i=1; i<(int)top_order.size(); i++)
cout << top_order[i] << " ";
cout << endl;
}
int main(){
setbuf(stdout, NULL);
int N, L, u, v;
scanf("%d %d", &N, &L);
Graph g(N+1);
for (int i=1; i<=L; i++){
scanf("%d %d", &u, &v);
g.addEdge(u, v);
}
g.topologicalSort();
return 0;
}
要检查特定图是否具有唯一的拓扑排序,显然检查 DAG 中的哈密顿路径就足够了。引用维基百科:
If a topological sort has the property that all pairs of consecutive vertices in the sorted order are connected by edges, then these edges form a directed Hamiltonian path in the DAG. If a Hamiltonian path exists, the topological sort order is unique; no other order respects the edges of the path. Conversely, if a topological sort does not form a Hamiltonian path, the DAG will have two or more valid topological orderings, for in this case it is always possible to form a second valid ordering by swapping two consecutive vertices that are not connected by an edge to each other. Therefore, it is possible to test in linear time whether a unique ordering exists.
所以你只需要为你找到的第一个排序获取 DAG,并检查它是否形成了一条访问所有顶点的路径。
在给定的代码中,如果您发现自己执行了两次或更多次 q.push() 作为一次 q.pop() 的结果,那么任何结果排序都不是唯一的。检查这个可能比检查汉密尔顿路径的结果 DAG 更麻烦。
这与此处评论中讨论的情况相同:Determine whether a directed graph has a unique topological ordering?
我创建了一个程序,在给定图表的情况下按拓扑排序组织图表。我确定了 3 个结果:
- 还行
- 现有周期
- 缺少信息
前两点的输出是正确的,但第三点不正确。例如对于有 4 个顶点和边的图:1->2; 3->1; 3->4; 4->2,我得到的结果是:3 1 4 2...错了!已知的不足以得出结论。 感谢任何提示或帮助,提前致谢。
#include<bits/stdc++.h>
using namespace std;
class Graph{
int V;
list<int> *adj;
public:
Graph(int V);
void addEdge(int u, int v);
void topologicalSort();
};
Graph::Graph(int V){
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int u, int v){
adj[u].push_back(v);
}
void Graph::topologicalSort(){
vector<int> in_degree(V, 0);
for (int u=0; u<V; u++){
list<int>::iterator itr;
for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
in_degree[*itr]++;}
queue<int> q;
for (int i = 0; i < V; i++)
if (in_degree[i] == 0)
q.push(i);
int cnt = 0;
vector <int> top_order;
while (!q.empty()){
int u = q.front();
q.pop();
top_order.push_back(u);
list<int>::iterator itr;
for (itr = adj[u].begin(); itr != adj[u].end(); itr++)
if (--in_degree[*itr] == 0)
q.push(*itr);
cnt++;}
if (cnt != V){
cout << "Existing cycle\n";
return;}
for (int i=1; i<(int)top_order.size(); i++)
cout << top_order[i] << " ";
cout << endl;
}
int main(){
setbuf(stdout, NULL);
int N, L, u, v;
scanf("%d %d", &N, &L);
Graph g(N+1);
for (int i=1; i<=L; i++){
scanf("%d %d", &u, &v);
g.addEdge(u, v);
}
g.topologicalSort();
return 0;
}
要检查特定图是否具有唯一的拓扑排序,显然检查 DAG 中的哈密顿路径就足够了。引用维基百科:
If a topological sort has the property that all pairs of consecutive vertices in the sorted order are connected by edges, then these edges form a directed Hamiltonian path in the DAG. If a Hamiltonian path exists, the topological sort order is unique; no other order respects the edges of the path. Conversely, if a topological sort does not form a Hamiltonian path, the DAG will have two or more valid topological orderings, for in this case it is always possible to form a second valid ordering by swapping two consecutive vertices that are not connected by an edge to each other. Therefore, it is possible to test in linear time whether a unique ordering exists.
所以你只需要为你找到的第一个排序获取 DAG,并检查它是否形成了一条访问所有顶点的路径。
在给定的代码中,如果您发现自己执行了两次或更多次 q.push() 作为一次 q.pop() 的结果,那么任何结果排序都不是唯一的。检查这个可能比检查汉密尔顿路径的结果 DAG 更麻烦。
这与此处评论中讨论的情况相同:Determine whether a directed graph has a unique topological ordering?