1. 拓撲排序問題(HDU 1285) php
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; public class Main { static int[] inDegree = new int[502]; static int[][] v = new int[502][502]; static boolean[] contain = new boolean[502]; public static void main(String[] args) throws IOException { StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); int n, m; while (in.nextToken() != StreamTokenizer.TT_EOF) { n = (int) in.nval; in.nextToken(); m = (int) in.nval; init(n); for (int i = 1; i <= m; i++) { in.nextToken(); int p1 = (int) in.nval; in.nextToken(); int p2 = (int) in.nval; if(v[p1][p2] == 0) { inDegree[p2]++; } v[p1][p2] = 1; } topologicalOrder(n); System.out.println(); } } private static void topologicalOrder(int n) { // TODO Auto-generated method stub int vv; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (inDegree[j] == 0 && contain[j]) { vv = j; contain[vv] = false; for (int j2 = 1; j2 <= n; j2++) { if (v[vv][j2] > 0) { inDegree[j2]--; } } System.out.print(vv); if(i != n) { System.out.print(" "); } break; } } } } private static void init(int n) { // TODO Auto-generated method stub for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { v[i][j] = 0; } inDegree[i] = 0; contain[i] = true; } } }上述代碼就是最簡單的拓撲排序,裏面有不少能夠優化的地方,好比用若是數據稀疏的話能夠用鄰接表來代替二維數組(矩陣),在找編號最小的且度爲0的頂點,能夠使用最小堆( 優先隊列)。下面代碼使用優先隊列來代替本來的遍歷查找,使複雜度下降。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; import java.util.PriorityQueue; import java.util.Queue; public class Main { static int[] inDegree = new int[502]; static int[][] v = new int[502][502]; public static void main(String[] args) throws IOException { StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); int n, m; while (in.nextToken() != StreamTokenizer.TT_EOF) { n = (int) in.nval; in.nextToken(); m = (int) in.nval; init(n); for (int i = 1; i <= m; i++) { in.nextToken(); int p1 = (int) in.nval; in.nextToken(); int p2 = (int) in.nval; if (v[p1][p2] == 0) { inDegree[p2]++; } v[p1][p2] = 1; } topologicalOrder(n); System.out.println(); } } private static void topologicalOrder(int n) { // TODO Auto-generated method stub int vv; Queue<Integer> queue = new PriorityQueue<Integer>(); for (int i = 1; i <= n; i++) { if (inDegree[i] == 0) { queue.add(i); } } for (int i = 1; i <= n; i++) { vv = queue.poll(); for (int j2 = 1; j2 <= n; j2++) { if (v[vv][j2] > 0) { inDegree[j2]--; if (inDegree[j2] == 0) { queue.add(j2); } } } System.out.print(vv); if (i != n) { System.out.print(" "); } } } private static void init(int n) { // TODO Auto-generated method stub for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { v[i][j] = 0; } inDegree[i] = 0; } } }直接把入度爲0的頂點放到優先隊列中(普通的拓撲排序只用普通隊列/棧/數組便可,這裏題目中有要求,相同入度爲0的點要求序號小的先輸出,因此使用優先隊列),使用隊列減小了一遍遍的遍歷全部點的入度。
在使用BFS和Dijkstra的優先隊列中都要使用到隊列,關於Dijkstra以及最短路徑算法,請查看最短路徑算法
java
系列: 算法
【算法系列 三】 Quene spa
【算法系列 四】 String .net