1. 문제
https://www.acmicpc.net/problem/1948
1948번: 임계경로
첫째 줄에 도시의 개수 n(1 ≤ n ≤ 10,000)이 주어지고 둘째 줄에는 도로의 개수 m(1 ≤ m ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 도로의 정보가 주어진다. 처음에는 도로의
www.acmicpc.net
2. 접근 방식
위상정렬로 접근한다. 단, 마지막 도시에 도착 후 역순으로 1분도 쉬지않고 달리는 도로를 찾아야한다.
3. 구현
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main1948 {
static int n,m;
static int[] indegree;
static List<Node>[] nodes;
static List<Node>[] reverseNodes;
static int[]timeStack;
static int cnt;
static class Node {
int target;
int time;
public Node (int target, int time) {
this.target = target;
this.time = time;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
m = Integer.parseInt(br.readLine());
indegree = new int[n+1];
nodes = new ArrayList[n+1];
reverseNodes = new ArrayList[n+1];
timeStack = new int[n+1];
for (int i=1; i<=n; i++) {
nodes[i] = new ArrayList<Node>();
reverseNodes[i] = new ArrayList<Node>();
}
StringTokenizer st;
for (int i=0; i<m; i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
int time = Integer.parseInt(st.nextToken());
nodes[start].add(new Node(end, time));
reverseNodes[end].add(new Node(start, time));
indegree[end]++;
}
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
topologicalSort(start, end);
findCriticalPath(start, end);
System.out.println(timeStack[end]);
System.out.println(cnt);
}
public static void findCriticalPath(int start, int end) {
boolean[] visited = new boolean[n+1];
Queue<Integer> q = new LinkedList<Integer>();
q.add(end);
visited[end] = true;
while (!q.isEmpty()) {
int now = q.poll();
for (Node next : reverseNodes[now]) {
if (timeStack[next.target] + next.time == timeStack[now]) {
cnt++;
if (!visited[next.target]) {
visited[next.target] = true;
q.add(next.target);
}
}
}
}
}
public static void topologicalSort(int start, int end) {
Queue<Integer> q = new LinkedList<Integer>();
q.add(start);
while(!q.isEmpty()) {
int now = q.poll();
for (Node next : nodes[now]) {
indegree[next.target]--;
timeStack[next.target] = Math.max(timeStack[next.target], next.time+timeStack[now]);
if (indegree[next.target] == 0) {
q.add(next.target);
}
}
}
}
}
4. 정리
'백준' 카테고리의 다른 글
백준 1916번 자바 (0) | 2023.04.04 |
---|---|
백준 1753번 자바 ☆ (0) | 2023.04.03 |
백준 1516번 자바 (0) | 2023.03.29 |
백준 2252번 자바 (0) | 2023.03.27 |
백준 1043번 자바 ☆ (0) | 2023.03.25 |