拓扑排序

  1. 1. 拓扑排序

【问题描述】

拓扑排序的流程如下:

1. 在有向图中选一个没有前驱的顶点并且输出之;

2. 从图中删除该顶点和所有以它为尾的弧。

重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。后一种情况则说明有向图中存在环。

采用邻接表存储有向图(可参考本次实验第2题代码),并通过栈来暂存所有入度为零的顶点。拓扑排序算法请参考教材上算法7.11和7.12或课件上的相应算法。

在本题中,读入一个有向图的信息(输入形式同本次实验第2题,详见下述【输入形式】),建立有向图并按照上述算法判断此图是否有回路,如果没有回路则输出拓扑有序的顶点数据序列。顶点的数据类型为int型。

注意:顶点编号从0开始。

【输入形式】仿照算法7.2的输入:

第1行输入图的结点个数n。第2行是图的各顶点数据。

之后的若干行(有向图为e行, 无向图为2e行) 依次输入各条边的弧尾、弧头的顶点编号。注意:因为算法7.2是按头插法建边链表的,所以要使得到的每个边链表中 都是按照邻接顶点的编号由小到大的顺序链接存储,就必须输入各边的顺序 首先是按照弧尾编号由小到大的顺序,并且输入弧尾相同的各边时 按照弧头顶点编号由大到小的顺序输入这些边,具体见样例输入。

最后一行输入-1和-1表示输入结束。

【输出形式】

如果读入的有向图含有回路,请输出“ERROR”,不包括引号。

如果读入的有向图不含有回路,请按照题目描述中的算法依次输出图的拓扑有序序列,每个整数后输出一个空格。

请注意行尾输出换行。

【样例输入】
4

0(空格)1(空格)2(空格)3

0(空格)1

1(空格)2

3(空格)2

-1(空格)-1

【样例输出】

3(空格)0(空格)1(空格)2(空格)

【说明】

本题中,需要严格的按照题目描述中的算法进行拓扑排序,并在排序的过程中将顶点数据先依次存储下来,直到最终能够判定有向图中不含回路之后,才能够进行输出,否则不能通过测试数据。

#include 
using namespace std;
struct edgenode
{
    int adj;
    edgenode *next;
};
typedef struct vnode
{
    int data;
    edgenode *first;
} adjlist[100];
struct graph
{
    adjlist vertices;
    int vexnum, arcnum;
};
int innode[500];
int store[500];
void create(graph **g)
{
    *g = new graph;
    cin >> (*g)->vexnum;
    for (int i = 0; i < (*g)->vexnum; i++)
    {
        cin >> (*g)->vertices[i].data;
        (*g)->vertices[i].first = NULL;
    }
    while (1)
    {
        int i, j;
        cin >> i >> j;
        if (j == -1 && i == -1)
            break;
        else
        {
            edgenode *p = new edgenode;
            p->adj = j;
            p->next = (*g)->vertices[i].first;
            (*g)->vertices[i].first = p;
        }
    }
}
void getinnode(graph *g)
{
    fill(innode, innode + g->vexnum, 0);
    for (int i = 0; i < g->vexnum; i++)
    {
        edgenode *p = g->vertices[i].first;
        while (p)
        {
            innode[p->adj]++;
            p = p->next;
        }
    }
}
void topologicasort(graph *g)
{
    getinnode(g);
    stack s;
    for (int i = 0; i < g->vexnum; i++)
    {
        if (!innode[i])
            s.push(i);
    }
    int count = 0;
    while (!s.empty())
    {
        int temp = s.top();
        store[count++] = s.top();
        s.pop();
        for (edgenode *p = g->vertices[temp].first; p; p = p->next)
        {
            int k = p->adj;
            if (!(--innode[k]))
                s.push(k);
        }
    }
    if (count < g->vexnum)
        cout << "ERROR";
    else
    {
        for (int i = 0; i < count; i++)
            cout << store[i] << " ";
    }
}
int main()
{
    graph *g;
    create(&g);
    topologicasort(g);
}

你可能感兴趣的:(图论,算法,数据结构)