赞
踩
拓扑排序指的是在一个有向图中,对所有的节点进行排序,要求没有一个节点指向它前面的节点。
先统计所有节点的入度,将入度为0的节点分离出来,并存下这个节点,然后把这个节点指向的节点的入度减一。
一直做改操作,直到所有的节点都被分离出来。
如果最后不存在入度为0的节点,那就说明有环,不存在拓扑排序,也就是很多题目的无解的情况。
下面是算法的演示过程。
需要注意的是拓扑排序的序列不唯一。
下面是演示代码:
//邻接表写法 #include<iostream> #include<stdio.h> #include<queue> #include<vector> using namespace std; int T,n,m; vector<int>a[10001]; queue<int>q; int in[10001]; vector<int>ans; void init() //初始化 { for(int i=1;i<=n;i++) { a[i].clear(); //清空以i为头的所以向量! rd[i]=0; } while(!q.empty()) q.pop(); //清空队列。 ans.clear(); } void tp() { for(int i=0;i<n;i++) { if(in[i]==0) q.push(i); } while(!q.empty()) { int head=q.front(); q.pop(); ans.push_back(head); for(int i=0;i<a[head].size();i++) //遍历以head为头的所以向量。 { int y=a[head][i]; //被指向的向量。 in[y]--; //被指的向量的入度-1. if(in[y]==0) q.push(y); } } for(int i=0;i<ans.size();i++) printf( "%d ",ans[i] ); printf("\n"); } int main() { int c,b; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); init(); while(m--) { scanf("%d%d",&b,&c); a[b].push_back(c); //将c插入b为头的向量的第一个。 in[c]++; //被指向的向量入度+1。 } tp(); } return 0; }
//链式前向星写法 #include <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define fi first #define se second #define endl '\n' #define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0) using namespace std; const int N = 1e6 + 10, M = 2 * N; int h[N], e[M], ne[M], d[N], idx; int n, m; queue<int> Q; vector<int> ans; void init() { idx = 0; memset(h, -1, sizeof h); memset(d, 0, sizeof d); while(!Q.empty()) Q.pop(); ans.clear(); } void add(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx ++; } bool topsort() { for(int i = 1; i <= n; i ++) if(d[i] == 0) Q.push(i); while(Q.size()) { int head = Q.front(); ans.push_back(head); Q.pop(); for(int j = h[head]; ~j; j = ne[j]) { int l = e[j]; d[l] --; if(d[l] == 0) Q.push(l); } } return ans.size() == n; } int main() { int t; scanf("%d", &t); while(t --) { scanf("%d%d", &n, &m); init(); while(m --) { int a, b; scanf("%d%d", &a, &b); add(a, b); d[b] ++; } if(topsort()) { for(int i = 0; i < ans.size(); i ++) printf("%d ", ans[i]); puts(""); } else puts("-1"); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。