拓扑排序
2018-02-25 00:03
253 查看
拓扑排序
定义
对一个有向无环图(Directed Acyclic Graph简称DAG) G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。
过程简述:
从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
从图中删除该顶点和所有以它为起点的有向边。
重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。若当前图中不存在无前驱的顶点说明有向图中必存在环。
基本操作函数
topological_sort(n):对含有n个顶点的图进行拓扑排序并输出。代码模板(含详细注释)
这里用http://acm.hdu.edu.cn/showproblem.php?pid=1285作为模板题#include <stdio.h> #include <stdlib.h> #include <string.h> #define V 510 //最大顶点数 int G[V][V]; //图 int degree[V]; //记录各顶点的入度 void topological_sort(int n) //拓扑排序函数 { int i, j, k; for(i = 1; i <= n; i++){ for(j = 1; j <= n; j++){ if(degree[j] == 0){ //找到入度为0的顶点 printf("%d", j); //输出 degree[j]--; //将其入度减为-1 k = j; //用k记录此顶点 break; } } for(j = 1; j <= n; j++){ if(G[k][j] == 1){ //找到被此顶点打败过的顶点 G[k][j] = 0; //标记 degree[j]--; //将找到的顶点的入度减一 } } if(i != n) printf(" "); else printf("\n"); } } int main(void) { int n; //队伍的个数 int m; //每组数据后接的输入行数 while(scanf("%d%d", &n, &m) != EOF){ memset(G, 0, sizeof(G)); //图的初始化 memset(degree, 0, sizeof(degree)); //顶点入度的初始化 while(m--){ int u, v; scanf("%d%d", &u, &v); //u打败了v if(G[u][v] == 0){ /*去重 这里要记录的是v被多少人打败过, 而不是被打败了多少次 */ G[u][v] = 1; //u打败过v degree[v]++; //顶点v的入度加一 } } topological_sort(n); //调用拓扑排序函数 } return 0; }
相关文章推荐
- 图的拓扑排序
- hdu 2094 产生冠军 实实在在的水题啊!就是连拓扑排序都不要。直接统计入度就可以了
- codeforces 510c (拓扑排序)
- POJ 1094 Sorting It All Out(拓扑排序)
- HDU1285_拓扑排序
- hdu 5195 BC#35 拓扑排序 优先队列 重复入队的想法 十字链表
- 拓扑排序
- 拓扑排序
- codeforces 510 C Fox And Names【拓扑排序】
- BZOJ4012【拓扑排序】
- POJ1094Sorting It All Out 拓扑排序
- poj 1094 Sorting It All Out 【拓扑排序】
- 拓扑排序
- hihoCoder 47周 拓扑排序
- POJ 1094 拓扑排序
- 拓扑排序模板-每次找入度为0的点都循环每一个点
- 确定比赛名次(拓扑排序)
- 算法导论 第二十二章:拓扑排序
- uva 10305 Ordering Tasks(拓扑排序)
- 拓扑排序