문제

https://www.acmicpc.net/problem/10282

접근방법

다익스트라, 기본 개념을 다룰 수 있는 문제

풀이코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

	static final int INF = 987654321;
	static int N, D, C, ans;
	static int[] dist;
	static ArrayList<Hack>[] list;
	
	private static class Hack implements Comparable<Hack>{
		int idx, time;
		public Hack(int idx, int time) {
			super();
			this.idx = idx;
			this.time = time;
		}
		@Override
		public int compareTo(Hack h) {
			return this.time - h.time;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		int T  = Integer.parseInt(in.readLine());
		for(int t=1; t<=T; ++t) {
			// 1. 입력 및 초기화
			ans = 0;
			StringTokenizer st = new StringTokenizer(in.readLine(), " ");
			N = Integer.parseInt(st.nextToken()); // 정점 (컴퓨터 수)
			D = Integer.parseInt(st.nextToken()); // 간선 (의존성 개수)
			C = Integer.parseInt(st.nextToken()); // 시작점 (해킹당한 컴퓨터)
			
			dist = new int[N+1];
			Arrays.fill(dist, INF);
			
			list = new ArrayList[N+1];
			for(int i=1; i<=N; i++) list[i] = new ArrayList<Hack>();
			
			// 2. 간선 리스트 (b->a)
			for(int i=0; i<D; i++) {
				st = new StringTokenizer(in.readLine(), " ");
				int from = Integer.parseInt(st.nextToken());
				int to   = Integer.parseInt(st.nextToken());
				int time = Integer.parseInt(st.nextToken());
				
				list[to].add(new Hack(from, time));
			}
			
			
			// 3. 다익스트라
			hacking();
			
			// 4. 감염되지 않는 컴퓨터들을 제외(INF)하고 정렬한다.
			int[] result = Arrays.stream(dist).filter(k -> k != INF).toArray();
			Arrays.sort(result);
			sb.append(ans+" "+result[result.length-1]).append('\n');
		}
		System.out.println(sb.toString().trim());
	}
	
	public static void hacking() {
		PriorityQueue<Hack> pque = new PriorityQueue<Hack>();
		boolean[] visited = new boolean[N+1];
		pque.add(new Hack(C, 0));
		dist[C] = 0;
		ans = 1;
		
		while(!pque.isEmpty()) {
			Hack from = pque.poll();
			
			//if(from.time > dist[from.idx]) continue; // 더 효율적인 백트랙킹 요소
			if(visited[from.idx]) continue;
			visited[from.idx] = true;
			
			for(Hack to : list[from.idx]) {
				if(dist[to.idx] > dist[from.idx] + to.time) {
					if(dist[to.idx] == INF) ans++; // 처음 감염되는 경로라면 감염컴퓨터수 증가
					dist[to.idx] = dist[from.idx] + to.time;
					pque.offer(new Hack(to.idx, dist[to.idx]));
				}
			}
		}
		
	}
}