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