본문 바로가기

알고리즘/백준

백준 - 1976번 여행 가자 - java

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

접근법

다른 사람들은 어떻게 풀었는지 꼭 확인이 필요..

  1. 마지막줄에 A->B->D... 이런식으로 여행가고자하는 지점을 주는데, 방문했던 장소를 다시가도 상관없고, 최단거리로 이동해야할 필요도 없음. 그래서

    이런식으로 생각함.
  2. 인접행렬이 주어지면, BFS를 통해 해당 노드로 부터 갈 수 있는 묶음(=ArrayList<Integer>)을 만들어줌
  3. 만들면서, INDEX[]배열에 각각의 노드가 어떤 인덱스 번호를 가진 위치에 속해있는지를 따로 결정해줌
  4. 가고자하는 첫번째 노드의 인덱스를 groupNum으로 지정하고, 가려고하는 모든 노드의 인덱스가 groupNum과 같은지를 비교 = 같은 그룹에 속해있는지 판단
    3-1. 탐색하다가 속해있지 않으면, NO 리턴. 끝까지 다 돌았으면 모두 속해있던거니 YES 리턴

소스

import java.util.*;
import java.io.*;

public class Main {
	static int N;
	static int M;
	static int[][] ADJ;
	static boolean[] VISIT;
	static ArrayList<ArrayList<Integer>> LIST;
	static int[] INDEX;
	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());
		st = new StringTokenizer(br.readLine());
		M = Integer.parseInt(st.nextToken());
		ADJ = new int[N][N];
		VISIT = new boolean[N];
		INDEX = new int[N];
		
		Arrays.fill(INDEX, -1);
		
		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0; j < N; j++) {
				int num = Integer.parseInt(st.nextToken());
				ADJ[i][j] = num;
			}
		}
		
		LIST = new ArrayList<ArrayList<Integer>>();
		
		for(int i = 0; i < N; i++) {
			if(!VISIT[i]) makeGraph(i);
		}
		
		ArrayList<Integer> travel = new ArrayList<Integer>();
		st = new StringTokenizer(br.readLine());
		for(int i = 0; i < M; i++) {
			travel.add(Integer.parseInt(st.nextToken())-1);
		}
		
		int groupNum = INDEX[travel.get(0)];
		for(int i = 1; i < travel.size(); i++) {
			if(groupNum != INDEX[travel.get(i)]) {
				System.out.println("NO");
				return;
			}
		}
		System.out.println("YES");
		
		
		
	}
	static void makeGraph(int idx) {
		ArrayList<Integer> graph = new ArrayList<Integer>();
		graph.add(idx);
		VISIT[idx] = true;

		Queue<Integer> q = new LinkedList<Integer>();
		q.offer(idx);
		
		while(!q.isEmpty()) {
			int cur = q.poll();
			
			for(int i = 0; i < N; i++) {
				//방문아직 안하고, 연결된 경우
				if(!VISIT[i] && ADJ[cur][i] == 1) {
					q.offer(i);
					VISIT[i] = true;
					graph.add(i);
				}
			}						
		}	
		LIST.add(graph);
		for(int i = 0; i < graph.size(); i++) {
			INDEX[graph.get(i)] = LIST.size();
		}
	}
}