貌似是第一次做了这 拓扑排序 应该是这题真的不难
先 让我们Look 题目
题目大意: 中文 理解起来没什么难度吧..... 单纯的拓扑排序
至于 它所要求的字典序 那就更简单了 只要我根据从1遍历到n 凡遇到可以取出的点 就将它标记取出 那就肯定是 取出的顺序是 从小到大了
拓扑排序呢 存在于DAG-----有向图 之中 将图中所有顶点排成一个线性序列 任意一对顶点u和v 若边(u,v)∈E
则u在线形序列中出现在v之前
这题呢 我们就给出代码来分析吧 因为 它实现起来不难 话说 我都是自己看着算法定义 就实现了.....
1 // 拓扑排序 有向无环图 DAG 将图中所有顶点排成一个线性序列 任意一对顶点u和v 若边(u,v)∈E 则u在线形序列中出现在v之前
2 // 寻找到入度为0的顶点 并删除与它相邻的边 然后继续寻找 直到找不到为止
3 #include <iostream>
4 using namespace std;
5
6 const int size = 520;
7 bool mp[size][size];
8 //int arr[size];
9 bool vis[size];
10 int in[size];
11
12 void topu( int n , int step )
13 {
14 int flag;
15 int i;
16 if( step==n )
17 {
18 return;
19 }
20 else
21 {
22 for( i = 1 ; i<=n ; i++ )
23 {
24 if( !vis[i]&&!in[i] )
25 {
26 vis[i] = true;
27 flag = i;
28 //arr[step] = i;
29 if( step==n-1 )
30 printf( "%d\n",flag );
31 else
32 printf( "%d ",flag );
33 break;
34 }
35 }
36 for( i = 1 ; i<=n ; i++ )
37 {
38 if( mp[flag][i] )
39 {
40 in[i]--;
41 }
42 }
43 topu( n , step+1 );
44 }
45 }
46
47 int main()
48 {
49 int n , m;
50 int x , y;
51 while( ~scanf( "%d %d",&n,&m) )
52 {
53 memset( mp , false , sizeof(mp) );// x->y 之间有边 则是true
54 memset( vis , false , sizeof(vis) );//标记 是否被访问过
55 while( m-- )
56 {
57 scanf( "%d %d",&x,&y );
58 mp[x][y] = true;// x 出发
59 in[y]++; //入度 +1
60 }
61 topu( n , 0 );
62 }
63 return 0;
64 }
嗯 有些拓扑排序比这个还要复杂多了 =下次 我们遇到了 再说
TOJ---3651---拓扑排序
时间: 2024-10-17 02:58:17