- 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 <bits/stdc++.h>
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<int> 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);
}