对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。
拓扑排序算法的基本步骤:
- 构造一个队列q 和 拓扑排序的结果队列ans;
- 把所有没有依赖顶点的节点(即入度为0的点)放入q;
- 当q队列非空时,队首元素u出队,u进入ans队列。对所有u开始的边,它的终点v入度均减1。发现新的入度为0的点则将其加入q。重复3直到q为空。
代码:
public class TopologicalSort {
static ArrayList<Integer>[] e = new ArrayList[1001];
static Queue<Integer> q = new LinkedList<Integer>();
static int[] in = new int[1001];
static int[] ans = new int[1001];
static int index;
public static void main(String[] args) throws IOException {
StreamTokenizer input = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int n,m;
input.nextToken(); n = (int)input.nval;
input.nextToken(); m = (int)input.nval;
int u,v;
for(int i=0;i<=n;i++){
e[i] = new ArrayList<Integer>();
}
for(int i=1;i<=m;i++){
input.nextToken(); u = (int)input.nval;
input.nextToken(); v = (int)input.nval;
e[u].add(v);
in[v]++; //记录入度
}
for(int i=1;i<=n;i++){
if(in[i]==0){
q.offer(i); //将入度为0的点加入队列
}
}
while(!q.isEmpty()){
int p = q.poll();
ans[index++] = p;
for(int i=0;i<e[p].size();i++){
int k = e[p].get(i);
in[k]--;
if(in[k]==0){
q.offer(k);
}
}
}
if(index==n){ //不为N说明存在环
for(int i=0;i<index;i++){
System.out.println(ans[i]);
}
}else{
System.out.println("不存在拓扑序");
}
}
}