C语言/C++,基于优先级队列的拓扑排序。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言/C++,基于优先级队列的拓扑排序。相关的知识,希望对你有一定的参考价值。

#include <iostream>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;

#define SIZE 100010

struct less_cmp

    bool operator()(const int &a, const int &b)
    
        return a > b;
    
;

vector<int> Vec[SIZE];
priority_queue < int, vector<int>, less_cmp > Que;
int n, k, degree[SIZE];

void clear()

    memset(degree, 0, sizeof(degree));


int main(int argc, char *argv[])

    int i, beg, end;

    while (1)
    
        scanf("%d %d", &n, &k);
        if (0 == n && 0 == k)
            break;

        for (i=0 ; i<k ; i++)
        
            scanf("%d %d", &beg, &end);
            Vec[beg].push_back(end);
            degree[end]++;
        
        
        /* 初始化,将所有入度为0的点加入优先级队列 */
        for (i=1 ; i<=n ; i++)
        
            if (0 == degree[i])
                Que.push(i);
        

        int node;
        vector<int>::iterator iter_beg;
        vector<int>::iterator iter_end;
        printf("ORDER:");
        while (!Que.empty())
        
            node = Que.top();
            Que.pop();
            printf(" %d", node);
            iter_end = Vec[node].end();
            /* 将选出的节点的相邻节点入度减一,如果减后入度为0,入队列 */
            for (iter_beg = Vec[node].begin() ; iter_beg != iter_end ; iter_beg++)
            
                degree[*iter_beg]--;
                if (0 == degree[*iter_beg])
                    Que.push(*iter_beg);
            
            Vec[node].clear();
        
        printf("\\n");

        clear();
    

Sample Input

5 6
1 4
4 3
1 5
5 3
1 3
2 4
0 0


Sample Output

ORDER: 1 2 4 5 3

参考技术A #include <iostream>
using namespace std;

#define MAX_VERTEX_NUM 20
struct adjVertexNode

int adjVertexPosition;
adjVertexNode* next;
;
struct VertexNode

char data[2];
adjVertexNode* list;
int indegree;
;
struct Graph

VertexNode VertexNode[MAX_VERTEX_NUM];
int vertexNum;
int edgeNum;
;

void CreateGraph (Graph& g)

int i, j, edgeStart, edgeEnd;
adjVertexNode* adjNode;
cout << "Please input vertex and edge num (vnum enum):" <<endl;
cin >> g.vertexNum >> g.edgeNum;
cout << "Please input vertex information (v1)/n note: every vertex info end with Enter" <<endl;
for (i=0;i<g.vertexNum;i++)

cin >> g.VertexNode[i].data; // vertex data info.
g.VertexNode[i].list = NULL;
g.VertexNode[i].indegree = 0;

cout << "input edge information(start end):" <<endl;
for (j=0; j<g.edgeNum; j++)

cin >>edgeStart >>edgeEnd;
adjNode = new adjVertexNode;
adjNode->adjVertexPosition = edgeEnd-1; // because array begin from 0, so it is j-1
adjNode->next=g.VertexNode[edgeStart-1].list;
g.VertexNode[edgeStart-1].list=adjNode;
//每增加一条边,则边的End顶点的入度加1
g.VertexNode[edgeEnd-1].indegree++;



void PrintAdjList(const Graph& g)

cout << "The adjacent list for graph is:" << endl;
for (int i=0; i < g.vertexNum; i++)

cout<< g.VertexNode[i].data << "->";
adjVertexNode* head = g.VertexNode[i].list;
if (head == NULL)
cout << "NULL";
while (head != NULL)

cout << head->adjVertexPosition + 1 <<" ";
head = head->next;

cout << endl;



VertexNode& FindZeroIndegree(Graph& g)

for (int i=0; i<g.vertexNum; i++)

if (g.VertexNode[i].indegree==0)
return g.VertexNode[i];

return g.VertexNode[0];

void TopSort(Graph& g)

cout << "The topsort is:" <<endl;
for (int i=0; i<g.vertexNum; i++)

VertexNode& v = FindZeroIndegree(g);
if (v.indegree!=NULL)
cout << "The graph has cycle, can not do topsort"<<endl;
// print graph as topsort.
cout<< v.data << " ";
// for each vertex w adjacent to v, --indegree
adjVertexNode* padjv = v.list;
while (padjv!=NULL)
//!!这个算法这里破坏了原图中的入度信息。最后入度均为1
g.VertexNode[padjv->adjVertexPosition].indegree--;
padjv = padjv->next;

//避免入度信息均为零FindZeroIndegree找到删除的顶点,将删除的顶点入度置为1
v.indegree++;

cout << endl;


void DeleteGraph(Graph &g)

for (int i=0; i<g.vertexNum; i++)

adjVertexNode* tmp=NULL;
while(g.VertexNode[i].list!=NULL)

tmp = g.VertexNode[i].list;
g.VertexNode[i].list = g.VertexNode[i].list->next;
delete tmp;
tmp = NULL;



int main(int argc, const char** argv)

Graph g;
CreateGraph(g);
PrintAdjList(g);
TopSort(g);
DeleteGraph(g);

return 0;

HDU-4857-逃生-反向拓扑排序+优先队列

HDU-4857

题意就是做一个符合条件的排序,用到拓扑序列。

我一开始wa了多发,才发现有几个样例过不了,发现1->2->3...的顺序无法保证。

后来就想用并查集强连,还是wa;

后来发现发用反向拓扑排序+优先队列才可以通过;

这里注意把入度为0的入队改成了出度为0的入队

下面是AC代码:

#include <cstring>
#include<queue>
#include <cstdio>
using namespace std;
vector<int>to[30000+10];
int n,m,cnt;
int outdeed[30000+10],topo [30000+10];
void init(){
    memset(outdeed,0,sizeof(outdeed));
    for(int i=1;i<=n;i++)
        to[i].clear();
    memset(topo,0,sizeof(topo));
}
void toposort()
{
    priority_queue<int>q;
    for(int i=1;i<=n;i++)
        if(!outdeed[i])q.push(i);
    cnt=0;
    while(!q.empty())
    {
        int tmp = q.top();
        q.pop();
        topo[++cnt]=tmp;
        int k = to[tmp].size();
        for(int i=0;i<k;i++)
        {
            int tt = to[tmp][i];
            outdeed[tt]--;
            if(outdeed[tt]==0)q.push(tt);
        }
    }
}
void output()
{
    for(int i=n;i>=1;i--)
        printf("%d%c",topo[i],i==1?\n: );
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%d%d",&n,&m);
        init();
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            to[v].push_back(u);
            outdeed[u]++;
        }
        toposort();
        output();
    }

    return 0;
}

 

以上是关于C语言/C++,基于优先级队列的拓扑排序。的主要内容,如果未能解决你的问题,请参考以下文章

数据结构(C语言版) 图的遍历和拓扑排序

图的深度优先搜索及拓扑排序

LeetCode 807. 保持城市天际线 / 630. 课程表 III(贪心+优先队列)/ 851. 喧闹和富有(拓扑排序)

如何用C++语言实现AOV网的所有拓扑排序?(最好能实现动态演示)

图的深度/广度优先遍历C语言程序

C语言实现优先队列(priority queue)