图论之拓扑排序各种写法

图的存储主要有邻接矩阵与邻接表两种写法,其中邻接表多采用vector<Edge> edge[N]方式模拟单链表简化存储。

struct Edge
{
  int nextNode;//下一个节点编号
  int cost;//该边权重
};

vector<Edge> edge[N];//为每个节点都模拟一个单链表

//清空,添加,遍历,删除
edge[i].clear();
edge[i].push_back();
for(int i=0;i<edge[2].size();i++){};
edge[2].erase(edge[2].begin()+i,edge[2].begin()+i+1);//删除edge[2][i]

BFS拓扑:

vector<int> edge[501];
queue<int> Q;//入度为0的节点队列
int inDegree[501];
init();//初始化,读入邻接表
while(Q.empty()==false)Q.pop();//清空上一组测试遗留数据
for(int i=0;i<n;i++)
{
    if(inDegree[i]==0)Q.push(i);
}
int cnt=0;
while(Q.empty()==false)
{
    int nowP=Q.front();
    Q.pop();
    cnt++;
    for(int i=0;i<edge[nowP].size();i++)
       {
           inDegree[edge[nowP][i]]--;
           if(inDegree[edge[nowP][i]]==0)
              Q.push(edge[nowP][i]);
       } 
}
if(cnt==n)puts("DAG");
else puts("circle");

DFS+stack拓扑:

vector<int> Edge[N];//假设无权值
int vis[N],top=0,stack[N];
void topo_sort(int x) {  
    vis[x] = 1;  
    for(int i=0;i<Edge[x].size();i++)
    {  
       if(vis[Edge[x][i]] == 0)  
         topo_sort(Edge[x][i]);  
    }     
    stack[top++] = Edge[x][i];  
} 

此时的stack也可用链表头插法,两者等价,作用为转化逆拓扑序列。

附:邻接表的写法也有采用数组的与vector模拟单链表类似,代码如下:

int head[N];//child正向
vector<int> p[maxn];//parent反向
struct Edge    
{    
    int to;
    int next;    
}edge[MAXN]; 

int cnt=0;

void addEdge(int u,int v)
{
    edge[cnt].to = v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}

void init()
{
    memset(head,-1,sizeof(head));    
    memset(inDegree,0,sizeof(inDegree));    
    for(int i = 0; i <= n; i++) p[i].clear(); 
}

//添加
addedge(u,v);  //child正向 
p[v].push_back(u); //parent反向  
inDegree[v]++;  //indegree  

//遍历
for(int i = head[u]; i != -1; i = edge[i].next){};
原文地址:https://www.cnblogs.com/demian/p/6537844.html