문제
23741번: 야바위 게임
첫 번째 줄에 정점 수 $N$, 간선 수 $M$, 게임 시작 시 공이 놓여있는 정점 번호 $X$, 공이 든 컵이 움직인 횟수 $Y$가 주어진다. ($1 \leq N, Y \leq 10^3$, $1 \leq M \leq 10^4$, $1 \leq X \leq N$) 다음 줄부터 $M$
www.acmicpc.net
문제 풀이
dfs+dp 문제. 처음에 dfs로만 했다가 시간초과떴다.
dfs로는 시작 정점에서 움직인 횟수를 카운트하면서 모든 경우에 대해 도착 지점을 확인한다.
dp로는 해당 지점과 같은 카운트를 가지고 온 경우는 처리하지 않도록 표시해둔다.
DP[i][j] = i노드의 j번의 횟수로 가는 모든 경우를 처리 했는가? → true
DFS에서는 해당 노드와 카운트를 가지고 다시 DFS를 수행할지 결정한다.
소스 코드
public class Main {
static ArrayList<Integer>[] g;
static boolean[][] dp;
static int[] answer;
static int Y, idx = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] str = br.readLine().split(" ");
int N = Integer.parseInt(str[0]); //정점개수
int M = Integer.parseInt(str[1]); //간선 수
int X = Integer.parseInt(str[2]); //공 처음정점
Y = Integer.parseInt(str[3]); //공 움직임 횟수
g = new ArrayList[N+1];
for(int i = 1; i < N+1; i++)
g[i] = new ArrayList<Integer>();
dp = new boolean[N+1][Y+1];
answer = new int[N+1];
for(int i = 0; i < M; i++) {
str = br.readLine().split(" ");
int a = Integer.parseInt(str[0]);
int b = Integer.parseInt(str[1]);
g[a].add(b);
g[b].add(a);
}
dfs(X, 0);
if(answer[0] == 0)
System.out.println("-1");
else {
Arrays.sort(answer, 0, idx);
for(int i = 0; i < idx; i++)
System.out.print(answer[i] + " ");
}
}
public static void dfs(int node, int total) {
dp[node][total] = true; //현재 이 노드에서 total개수를 가지고 갈 수 있는 경우는 다 봤다
if(total == Y) {
answer[idx++] = node;
return;
}
for(int i = 0; i < g[node].size(); i++) { //시작 노드에 연결된 개수만큼 돌면서
int nextNode = g[node].get(i); //연결된 다른 노드
if(!dp[nextNode][total+1])
dfs(nextNode, total+1);
}
return;
}
}
'Algorithm > BOJ' 카테고리의 다른 글
[백준] 9935번 문자열 폭발 자바 (0) | 2022.04.20 |
---|---|
[백준] 23742번 Player-based Team Distribution 자바 (0) | 2022.04.18 |
[백준] 9012번 괄호 자바 (0) | 2022.04.14 |
[백준] 1904번 01타일 자바 (0) | 2022.04.13 |
[백준] 1937번 욕심쟁이 판다 자바 (0) | 2022.04.07 |