我创建了一个程序,通过给定图表的拓扑排序来组织图形。我确定了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;
}
答案 0 :(得分:1)
在给定的代码中,如果您发现自己执行了两个或多个 q.push() 作为一个 q.pop() 的结果,那么任何结果排序都将不是唯一的。检查这一点可能比检查哈密顿路径的结果 DAG 麻烦。
这与此处评论中讨论的条件相同:Determine whether a directed graph has a unique topological ordering?
答案 1 :(得分:0)
要检查特定图形是否具有唯一的拓扑排序,显然足以检查DAG中的哈密顿路径。引用维基百科:
如果拓扑排序具有排序顺序中所有连续顶点对通过边连接的属性,则这些边在DAG中形成有向哈密顿路径。如果存在哈密尔顿路径,则拓扑排序顺序是唯一的;没有其他顺序尊重路径的边缘。相反,如果拓扑排序不形成哈密顿路径,则DAG将具有两个或更多有效的拓扑排序,因为在这种情况下,总是可以通过交换两个未通过边连接的连续顶点来形成第二个有效排序对彼此。因此,可以在线性时间内测试是否存在唯一排序。
因此,您只需要为找到的第一个排序获取DAG,并检查它是否形成了访问所有顶点的路径。