题意:
给定n个点,与m条边, 给出他们的拓扑排序。
分析:
拓扑排序可以有两种做法, 第一种是dfs, 每次都找到某一个点的终点, 然后加入序列末尾, 正在访问的标记为-1, 访问过的标记为1, 未访问的标记为0
int c[maxn]; vector<int> G[maxn]; stack<int> s; bool dfs(int u){ c[u] = -1;//标记为正在访问 for(int i = 0; i < G[i].size(); i++){ int v = G[u][i]; if(c[v] == -1) return false;//如果访问到正在访问的点, 说明有环 if(c[v] == 0){//如果没访问过 if(!dfs(v)) return false; //访问该点, 如果该点(或该点的孩子)访问到正在访问, 说明有环 } } c[u] = 1;//标记为以访问 s.push(u);//入栈 return true; } void toposort(){ for(int i = 1; i <= n; i++) if(!c[i]){//没访问过 if(!dfs(i)) return false; } return true; }
1 #include <bits/stdc++.h> 2 using namespace std; 3 int Matrix[102][102]; 4 int c[102]; 5 int n, m, t; 6 int topo[102]; 7 bool dfs(int u){ 8 // printf("%d %d ", u, c[u]); 9 c[u] = -1; 10 for(int v = 1; v <= n; v++){ 11 if(Matrix[u][v]){ 12 if(c[v] < 0) return false; 13 else if(!c[v] && !dfs(v)) return false; 14 } 15 } 16 topo[--t] = u; 17 c[u] = 1; 18 return true; 19 } 20 21 bool toposort(){ 22 t = n; 23 for(int i = 1; i <= n; i++){ 24 if(!c[i]) 25 if(!dfs(i)) return false; 26 } 27 printf("%d",topo[0]); 28 for(int i = 1; i < n; i++){ 29 printf(" %d",topo[i]); 30 } 31 printf(" "); 32 } 33 int main(){ 34 #if LOCAL 35 freopen("1.txt","r",stdin); 36 #endif // LOCAL 37 while(scanf("%d %d", &n, &m)== 2 && n){ 38 memset(Matrix,0,sizeof(Matrix)); 39 memset(c,0,sizeof(c)); 40 for(int i = 0; i < m; i++){ 41 int u , v; 42 scanf("%d %d", &u, &v); 43 Matrix[u][v] = 1; 44 } 45 toposort(); 46 47 } 48 return 0; 49 }
第二种是标记每个点的入度, 每次都将入度为0的加入序列头部, 然后将他的出边的点的入度减去, 循环n次就能找出拓扑排序了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 int Matrix[102][102]; 4 int degree[102]; 5 int c[102]; 6 int n, m, t; 7 int topo[102]; 8 bool dfs(int u){ 9 // printf("%d %d ", u, c[u]); 10 c[u] = -1; 11 for(int v = 1; v <= n; v++){ 12 if(Matrix[u][v]){ 13 if(c[v] < 0) return false; 14 else if(!c[v] && !dfs(v)) return false; 15 } 16 } 17 topo[--t] = u; 18 c[u] = 1; 19 return true; 20 } 21 22 bool toposort(){ 23 t = n; 24 // for(int i = 1; i <= n; i++) 25 // printf("%d ",degree[i]); 26 // printf(" "); 27 while(t--){ 28 // for(int i = 1; i <= n; i++) 29 // printf("%d ",degree[i]); 30 // printf(" "); 31 32 int u; 33 for(int i = 1; i <= n; i++){ 34 if(degree[i] == 0 && c[i] == 0){ 35 c[i] = 1; 36 u = i; 37 break; 38 } 39 } 40 // printf("$$ %d %d ", u, t); 41 for(int i = 1; i <= n; i++) 42 if(Matrix[u][i]) degree[i] --; 43 topo[n-t-1] = u; 44 } 45 printf("%d",topo[0]); 46 for(int i = 1; i < n; i++){ 47 printf(" %d",topo[i]); 48 } 49 printf(" "); 50 } 51 int main(){ 52 #if LOCAL 53 freopen("1.txt","r",stdin); 54 #endif // LOCAL 55 while(scanf("%d %d", &n, &m)== 2 && n){ 56 memset(Matrix,0,sizeof(Matrix)); 57 memset(c,0,sizeof(c)); 58 memset(degree,0,sizeof(degree)); 59 for(int i = 0; i < m; i++){ 60 int u , v; 61 scanf("%d %d", &u, &v); 62 Matrix[u][v] = 1; 63 degree[v]++; 64 } 65 toposort(); 66 67 } 68 return 0; 69 }