http://dsa.openjudge.cn/graph/0719/
0719:拓扑排序
- 总时间限制:
- 10000ms
- 内存限制:
- 1000kB
- 描述
给出一个图的结构,输出其拓扑排序序列,要求在同等条件下,编号小的顶点在前
- 输入
- 若干行整数,第一行有2个数,分别为顶点数v和弧数a,接下来有a行,每一行有2个数,分别是该条弧所关联的两个顶点编号
- 输出
- 若干个空格隔开的顶点构成的序列(用小写字母)
- 样例输入
6 8 1 2 1 3 1 4 3 2 3 5 4 5 6 4 6 5
- 样例输出
v1 v3 v2 v6 v4 v5
//北大数算课程上主要讲的拓扑排序使用邻接链表实现的,但如果空间要求没有非常高,邻接矩阵的表示方法依然是一个不错的选择 //为了节省很时间不去每次都把矩阵遍历一遍,用一个一位数组记录一个点的入度,每次按顺序找到一个入读为0的点,将入读修改为-1,并且修改以这个点为起始点的终点的入读和并清零矩阵上表示这条边的元素 再从头进行判断,直到找不到一个入读为0的点为止,为什么从头进行判断,这会费一些时间 ,不过能够更方便的满足小的节点在前面输出的条件
#include<iostream> #include<stdio.h> #include<cstring> using namespace std; #define maxn 500 bool data[maxn][maxn]; int ind[maxn]; int v,a; int main() { int s,d; memset(data,0,sizeof(data)); memset(ind,0,sizeof(ind)); scanf("%d%d",&v,&a); for(int i=0;i<a;i++) { scanf("%d%d",&s,&d); data[s][d]=1; ind[d]++; } for(int i=1;i<=v;i++) { if(ind[i]==0) { printf("v%d ",i); ind[i]--; for(int j=1;j<=v;j++) { if(data[i][j]) { data[i][j]=0; ind[j]--; } } i=0; } } return 0; }