当前位置: 代码迷 >> 综合 >> AcWing 848. 有向图的拓扑序列(拓扑排序)
  详细解决方案

AcWing 848. 有向图的拓扑序列(拓扑排序)

热度:6   发布时间:2024-02-09 07:28:04.0

给定一个n个点m条边的有向图,点的编号是1到n,图中可能存在重边和自环。

请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。

若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

输入格式

第一行包含两个整数n和m

接下来m行,每行包含两个整数x和y,表示存在一条从点x到点y的有向边(x, y)。

输出格式

共一行,如果存在拓扑序列,则输出拓扑序列。

否则输出-1。

数据范围

1≤n,m≤1051≤n,m≤105

输入样例:

3 3
1 2
2 3
1 3

输出样例:

1 2 3

import java.io.*;
import java.lang.*;
import java.util.*;
class Main{static int n = 0, m = 0, N = 100010;static int[] h = new int[N];//邻接表数组static int[] e = new int[N], ne = new int[N];//单链表static int idx = 1;static int[] q = new int[N], out = new int[N], in = new int[N];static void add(int a, int b){e[idx] = b; ne[idx] = h[a]; h[a] = idx++;out[a]++;//初度+1in[b]++;//入度+1}static boolean sort(){int hh = 0, tt = -1;for(int i = 1; i <= n; ++i){//所有入度为0的先进入队列if(in[i] == 0){q[++tt] = i;}}while(hh <= tt){int t = q[hh++];for(int i = h[t]; i != -1; i = ne[i]){int j = e[i];if(in[j]  != 0){in[j]--;out[t]--;}if(in[j] == 0){q[++tt] = j;}}}return tt == n - 1;}public static void main(String[] args)throws Exception{BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));String[] params = buf.readLine().split(" ");n = Integer.valueOf(params[0]);m = Integer.valueOf(params[1]);Arrays.fill(h, -1);for(int i = 1; i <= m; ++i){String[] info = buf.readLine().split(" ");int a = Integer.valueOf(info[0]);int b = Integer.valueOf(info[1]);add(a, b);//有向图}int t = 0;if(sort()){while(n-- != 0){System.out.print(q[t++] + " ");}}else{System.out.print(-1);}}
}