题解 | 【模板】拓扑排序
【模板】拓扑排序
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#

