07.위상 정렬 (Topological Sort)
위상 정렬 (Topological Sort)란?
- 위상 정렬 = 위상 + 정렬
- Directed Acyclic Graph (DAG)
- Directed := 간선에 방향성이 있다.
- Acyclic := Cyclic 이 없다.
- Graph := 정점(V) + 간선(E)
- 정점들을 위상에 맞춰 정렬
- 차수(Degree) 란?
- 제일 먼저 올 수 있는 정점은?
- 하나씩 정렬시켜 버리면서 그래프에서 삭제하기
- 정리
- 정점들의 Indegree, indeg[1…N] 계산하기
- 들어오는 간선이 0개인 (indeg[i] == 0) 정점들을 찾아서 자료구조 D 에 넣기
- D 가 빌 때까지
- D 에서 원소 x를 꺼내서 정렬 시키기
- Graph 에서 정점 x 제거 하기
- 새로게 정렬 가능한 점 을 찾아서 D에 넣기
- O(V + E)
- 자료구조 D 에 필요한 연산은?
- 원소를 추가하기
- 원소를 꺼내기
- 두 연산을 빠르게 해주는 것은 -> Queue
public class baekjoon2252 {
static int N, M;
static ArrayList<Integer>[] graph;
static int[] indeg;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
graph = new ArrayList[N + 1];
indeg = new int[N + 1];
for (int i = 1; i <= N; i++) graph[i] = new ArrayList<>();
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
graph[x].add(y);
indeg[y]++;
}
bfs2252();
System.out.println(sb);
}
private static void bfs2252() {
Queue<Integer> queue = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indeg[i] == 0) queue.add(i);
}
while (!queue.isEmpty()) {
int cur = queue.poll();
sb.append(cur).append(" ");
for (int y : graph[cur]) {
indeg[y]--;
if (indeg[y] == 0) queue.add(y);
}
}
}
}
public class baekjoon2623 {
static int N, M;
static ArrayList<Integer>[] graph;
static int[] indeg;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
graph = new ArrayList[N + 1];
indeg = new int[N + 1];
for (int i = 1; i <= N; i++) graph[i] = new ArrayList<>();
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int count, x, y;
count = Integer.parseInt(st.nextToken());
x = Integer.parseInt(st.nextToken());
for (int j = 2; j <= count; j++) {
y = Integer.parseInt(st.nextToken());
graph[x].add(y);
indeg[y]++;
x = y;
}
}
bfs2623();
}
private static void bfs2623() {
Deque<Integer> queue = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indeg[i] == 0) {
queue.add(i);
}
}
ArrayList<Integer> result = new ArrayList<>();
while (!queue.isEmpty()) {
int x = queue.poll();
result.add(x);
for (int y : graph[x]) {
indeg[y]--;
if (indeg[y] == 0) queue.add(y);
}
}
if (result.size() == N) {
for (int x : result) {
System.out.println(x);
}
} else {
System.out.println(0);
}
}
}
public class baekjoon9470 {
static int M, K, P;
static ArrayList<Integer>[] graph;
static int[] indeg, order, maxCnt;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int t = 0; t < T; t++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
K = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
P = Integer.parseInt(st.nextToken());
graph = new ArrayList[M + 1];
indeg = new int[M + 1];
order = new int[M + 1];
maxCnt = new int[M + 1];
for (int i = 1; i <= M; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < P; i++) {
st = new StringTokenizer(br.readLine(), " ");
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
graph[A].add(B);
indeg[B]++;
}
bfs9470();
}
}
private static void bfs9470() {
Deque<Integer> queue = new LinkedList<>();
for (int i = 1; i <= M; i++) {
if (indeg[i] == 0) {
queue.add(i);
order[i] = maxCnt[i] = 1;
}
}
int ans = 0;
while (!queue.isEmpty()) {
int x = queue.poll();
if (maxCnt[x] >= 2) order[x]++;
ans = Math.max(ans, order[x]);
for (int y : graph[x]) {
indeg[y]--;
if (indeg[y] == 0) {
queue.add(y);
}
if (order[x] == order[y]) maxCnt[y]++;
else if (order[y] < order[x]) {
order[y] = order[x];
maxCnt[y] = 1;
}
}
}
System.out.println(K + " " + ans);
}
}
public class baekjoon14676 {
static int N, M, K;
static ArrayList<Integer>[] graph;
static int[] indeg, checked, cnt;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
graph = new ArrayList[N + 1];
indeg = new int[N + 1];
checked = new int[N + 1];
cnt = new int[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
graph[x].add(y);
indeg[y]++;
}
boolean abnormal = false;
while (K-- > 0) {
st = new StringTokenizer(br.readLine(), " ");
int t = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(st.nextToken());
if (t == 1) {
if (checked[x] < indeg[x]) abnormal = true;
cnt[x]++;
if (cnt[x] == 1) {
for (int y : graph[x]) {
checked[y]++;
}
}
} else {
if (cnt[x] == 0) abnormal = true;
cnt[x]--;
if (cnt[x] == 0) {
for (int y : graph[x]) {
checked[y]--;
}
}
}
}
if (abnormal) System.out.println("Lier!");
else System.out.println("King-God-Emperor");
}
}
public class baekjoon1005 {
static int N, K, W;
static ArrayList<Integer>[] graph;
static int[] delay, indeg, time;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
while (T-- > 0) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
time = new int[N + 1];
indeg = new int[N + 1];
delay = new int[N + 1];
graph = new ArrayList[N + 1];
st = new StringTokenizer(br.readLine(), " ");
for (int i = 1; i <= N; i++) {
delay[i] = Integer.parseInt(st.nextToken());
}
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine(), " ");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
graph[x].add(y);
indeg[y]++;
}
W = Integer.parseInt(br.readLine());
bfs1005();
}
}
private static void bfs1005() {
Deque<Integer> deque = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indeg[i] == 0) {
deque.add(i);
time[i] = delay[i];
}
}
while (!deque.isEmpty()) {
int x = deque.poll();
for (int y : graph[x]) {
indeg[y]--;
if (indeg[y] == 0) deque.add(y);
time[y] = Math.max(time[y], time[x] + delay[y]);
}
}
System.out.println(time[W]);
}
}
public class baekjoon1516 {
static int N;
static ArrayList<Integer>[] graph;
static int[] delay, indeg, time;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
delay = new int[N + 1];
indeg = new int[N + 1];
time = new int[N + 1];
graph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 1; i <= N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int time = Integer.parseInt(st.nextToken());
delay[i] = time;
int next;
while ((next = Integer.parseInt(st.nextToken())) != -1) {
graph[next].add(i);
indeg[i]++;
}
}
bfs1516();
}
private static void bfs1516() {
Deque<Integer> deque = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indeg[i] == 0) {
deque.add(i);
time[i] = delay[i];
}
}
while (!deque.isEmpty()) {
int x = deque.poll();
for (int y : graph[x]) {
indeg[y]--;
if (indeg[y] == 0) deque.add(y);
time[y] = Math.max(time[y], time[x] + delay[y]);
}
}
for (int i = 1; i <= N; i++) System.out.println(time[i]);
}
}
public class baekjoon2056 {
static int N;
static ArrayList<Integer>[] graph;
static int[] indeg, delay, time;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
indeg = new int[N + 1];
delay = new int[N + 1];
time = new int[N + 1];
graph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 1; i <= N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int t = Integer.parseInt(st.nextToken());
delay[i] = t;
int c = Integer.parseInt(st.nextToken());
for (int j = 0; j < c; j++) {
int y = Integer.parseInt(st.nextToken());
graph[i].add(y);
indeg[y]++;
}
}
bfs2056();
}
private static void bfs2056() {
Deque<Integer> deque = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indeg[i] == 0) {
deque.add(i);
time[i] = delay[i];
}
}
while (!deque.isEmpty()) {
int x = deque.poll();
for (int y : graph[x]) {
indeg[y]--;
if (indeg[y] == 0) {
deque.add(y);
}
time[y] = Math.max(time[y], time[x] + delay[y]);
}
}
System.out.println(Arrays.stream(time).max().getAsInt());
}
}
public class baekjoon2637 {
static int N, M;
static ArrayList<int[]>[] graph;
static int[] indeg;
static int[][] count;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
indeg = new int[N + 1];
count = new int[N + 1][N + 1];
graph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
M = Integer.parseInt(br.readLine());
for (int i = 0; i < M; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
graph[y].add(new int[]{x, k});
indeg[x]++;
}
bfs2637();
}
private static void bfs2637() {
Deque<Integer> deque = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indeg[i] == 0) {
deque.add(i);
count[i][i] = 1;
}
}
while (!deque.isEmpty()) {
int x = deque.poll();
for (int[] info : graph[x]) {
int y = info[0];
int k = info[1];
indeg[y]--;
for (int i = 1; i <= N; i++) {
count[y][i] += count[x][i] * k;
}
if (indeg[y] == 0) deque.add(y);
}
}
for (int i = 1; i <= N; i++) {
if (count[N][i] != 0) System.out.println(i + " " + count[N][i]);
}
}
}