C++ 如何知道拓扑排序是否有效?

C++ 如何知道拓扑排序是否有效?,c++,topological-sort,C++,Topological Sort,我有这个1…n的图,现在我找到了一个拓扑排序解,我怎么知道它是否是一个有效解? 例如,对于n=5; 这种连通性 1->2, 2->3, 1->3, 1->5 我有一个解决方案4->1->5->2->3。它有效吗?可能是我对托普波特的想法不清楚 为了方便起见,这是我的代码 int incoming[n],A[n][n]; priority_queue<int> Q; while(m--){ int i,j; cin>>i>>j; A[i]

我有这个1…n的图,现在我找到了一个拓扑排序解,我怎么知道它是否是一个有效解? 例如,对于n=5; 这种连通性 1->2, 2->3, 1->3, 1->5

我有一个解决方案4->1->5->2->3。它有效吗?可能是我对托普波特的想法不清楚

为了方便起见,这是我的代码

int incoming[n],A[n][n];
priority_queue<int> Q;
while(m--){
    int i,j;
    cin>>i>>j;
    A[i][j] = 1;
    ++incoming[j];
}
for(int i=1;i<=n;++i)
    if(!incoming[i])
        Q.push(i);
vector<int> toplist;
while(!Q.empty()){
    int u = Q.top(); Q.pop();
    toplist.push_back(u);
    for(int i = 1;i<=n;++i)
    {
        if(A[u][i])
        {
            A[u][i] = 0;
            --incoming[i];
            if(!incoming[i])
                Q.push(i);
        }

    }
}
for(int i=0;i<toplist.size();++i)
    cout<<toplist[i]<<" ";
int传入[n],A[n][n];
优先级队列Q;
而(m--){
int i,j;
cin>>i>>j;
A[i][j]=1;
++传入[j];
}

对于(inti=1;i我的问题与我研究拓扑排序时的问题完全相同。 有一个名为bValidateTopSortResult()的函数用于验证结果。 如果存在从U到V的边,则在顶部排序中,U必须位于V之前。 重要的是要跟踪所有相邻的顶点。我已经存储在一个列表中

#include <iostream>
#include <list>
#include <stack>
#include <map>

using namespace std;

struct GRAPH{
    int iVertices;

list<int> *ptrAdj;  //Has structure like ptrAdj[i]={j,k,l}.  This means that
                    //i is from-vertex and j,k,l are to-vertices.
}; 

int iTopSortOrder[10];
map<int, int> mapTopSort;

//
//Recursive function.
//Key is iterating  list<>*ptrAdj.
//
void
vTopSortRecursive( GRAPH* pG, int iVertexID, bool *bVisited, stack<int>& stResult )
{
   bVisited[iVertexID] = true;

   //Goes thru all adjacent vertices. 
   for( auto it : pG->ptrAdj[iVertexID]){
       if(bVisited[it] == false) 
           vTopSortRecursive( pG, it, bVisited, stResult );
   }

    //Pushes the vertex ID after all its children adjacent vertices are already 
   pushed.
   stResult.push(iVertexID);
}

void
vTopSort( GRAPH* ptrGraph )
{
    stack<int> stResult;
    bool bVisited[ptrGraph->iVertices];
    int iTopSortIndex = 0;

    for(int i=0; i < ptrGraph->iVertices; ++i )
        bVisited[i] = false;


    for(int i=0; i < ptrGraph->iVertices; ++i )
        if(bVisited[i] == false )
            vTopSortRecursive( ptrGraph, i, bVisited, stResult );

    cout << "Top sort result" << endl;
    while( !stResult.empty() ){
        int iTop = stResult.top();
        cout << iTop << endl;
        //Keeps track of the order of the vertex top sort.
        //mapTopSort[i] = j means vertex ID 'i' is in jth order in array.
        mapTopSort[iTop] = iTopSortIndex;
        //Keeps the top sort order in an array.
        iTopSortOrder[iTopSortIndex] = stResult.top();;
        stResult.pop();
        iTopSortIndex++;
    }
}
//All parent ID must come befoe children ID in top sort.
//mapTopSort[i] = j;  means that vertex ID 'i' is in jth place in the order.
bool
bValidateTopSortResult( GRAPH* ptrGraph )
{
    bool bValid=true;

    for(int iVertexID=0; iVertexID<ptrGraph->iVertices;iVertexID++)
    {
        for(auto it: ptrGraph->ptrAdj[iVertexID] ){
            if( mapTopSort[iVertexID] > mapTopSort[it] ){

                bValid = false;
                cout << "Invalid sort" << endl;
                cout << iVertexID << " must come before " << mapTopSort[it] << endl;
            }
        }
    }
    return bValid;
}

int
main(void)
{
    GRAPH *ptrGraph = new GRAPH;
    ptrGraph->iVertices = 6;

    ptrGraph->ptrAdj = new list<int>[6];
    ptrGraph->ptrAdj[5].push_back(2); 
    ptrGraph->ptrAdj[5].push_back(0); 
    ptrGraph->ptrAdj[4].push_back(0); 
    ptrGraph->ptrAdj[4].push_back(1); 
    ptrGraph->ptrAdj[2].push_back(3); 
    ptrGraph->ptrAdj[3].push_back(1); 

    vTopSort( ptrGraph );

    if (bValidateTopSortResult( ptrGraph ))
        cout << "Sort is valid";
    else
        cout <<"Sort is INVALID";

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
结构图{
综合性;
list*ptrAdj;//具有类似ptrAdj[i]={j,k,l}的结构
//i是从顶点开始的,j,k,l是到顶点的。
}; 
int iTopSortOrder[10];
mapTopSort地图;
//
//递归函数。
//关键是迭代列表*ptrAdj。
//
无效的
VTOPSORTRECURSITE(图形*pG、int iVertexID、布尔*bVisited、堆栈和stResult)
{
bVisited[iVertexID]=真;
//穿过所有相邻的顶点。
用于(自动it:pG->ptrAdj[iVertexID]){
if(bVisited[it]==false)
vTopSortResult(pG、it、bVisited、stResult);
}
//在所有相邻顶点的子顶点都已完成后,推送顶点ID
推。
stResult.push(iVertexID);
}
无效的
vTopSort(图形*ptrGraph)
{
堆栈结果;
bool bVisited[ptrGraph->iferties];
int-iTopSortIndex=0;
对于(int i=0;iiferties;++i)
bVisited[i]=假;
对于(int i=0;iiferties;++i)
if(bVisited[i]==false)
VTOPSORTRECURSHIVE(PTRGRAPHE、i、BVISTITED、stResult);
cout-ptrAdj[3]。推回(1);
vTopSort(ptrGraph);
if(bValidateTopSortResult(ptrGraph))

cout拓扑排序是DAG上的简单DFS。如果你想证明算法产生正确的结果,你可以进行数学分析。
x
在拓扑排序中,如果存在从
x
y
的边,则在
y
之前出现
x
。知道这一点,你可以检查你的解是否有效。解是正确的,并且你的代码看起来也是正确的。你使用的是一个经过验证的算法,从实用的角度来说,它应该足够了,或者你是在要求一个证明?(很容易找到…)如果你想测试它,你可以在上面找到一个拓扑排序问题;)不,我不需要证明,我只是对我的算法不确定。谢谢你的帮助。