题解 | 【模板】拓扑排序
【模板】拓扑排序
https://www.nowcoder.com/practice/88f7e156ca7d43a1a535f619cd3f495c
import java.util.Arrays; import java.util.Scanner; public class Main { static int[] e, ne, h, d, q; static int idx, n, m; public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); // 点 m = in.nextInt(); // 边 while (m-- > 0) { int u = in.nextInt(); int v = in.nextInt(); add(u, v); d[v]++; //指向v的节点数:入度 } if (topSort()) { for (int i = 0; i < n; i++) { // 注意:输出的最后一个数后面不要带空格。 System.out.print(i == n - 1 ? q[i] : q[i] + " "); } } else { System.out.println(-1); } } static { e = new int [200001]; // 给idx,返回 值 ne = new int [200001]; // 给idx,返回 下一个节点的地址 h = new int[200001]; // 给节点的下标 ,返回 头节点的地址。链表、尾插法、头节点 d = new int[200001]; // 每个点的入度 q = new int[200001]; // 队列 idx = 0; //地址值 0 ~ n-1 Arrays.fill(h, -1); } //尾插法,获取一个地址值(自增):类似生成一个节点y(y是一个节点编号),然后把这个节点y加入到以x为头节点的链表中。y为新的头节点 // (x=1)->2->3 // y->(x=1) // (x=y)->1->2->3 public static void add(int x, int y) { e[idx] = y; ne[idx] = h[x]; h[x] = idx++; } public static boolean topSort() { int hh = 0, tt = -1; for (int i = 1; i <= n; i++) { if (d[i] == 0) {//若为0,则入队 q[++tt] = i; } } while (hh <= tt) { int t = q[hh++]; // 遍历从t出发可达节点的地址 for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; // 根据地址找出 节点的编号 if (--d[j] == 0) { // 入读减1若为0,则也入队 q[++tt] = j; } } } return n - 1 == tt; } }
看的acwing上的模板,拼尽全力艰难拿下。没有输的彻底!
https://www.acwing.com/file_system/file/content/whole/index/content/3272/
附上个链接。
#邻接表##拓扑排序##Java#