728x90
문제
접근 방식
각각의 구슬을 정점, 두 구슬의 대소 관계를 간선이라고 했을 때
정점 X에서 Y로 갈 수 있다면 구슬 X가 구슬 Y보다 무겁다는 것을 알 수 있다.
하지만 단방향 그래프로 인접 행렬을 표현하니 대소 관계가 제대로 처리가 되지 않고
일반적인 양방향으로 표현하자니 어느 구슬이 무거운지를 알 수가 없는 문제가 있었다.
그래서 인접 행렬을 만들 때 구슬 X가 Y보다 무겁다면
정점 X에서 Y로 갈 수 있는 것을 표시할 때 1로 표시를 해주고
구슬 X가 Y보다 가볍다면 -1로 표시를 해주었다.
그 후 각 구슬마다 DFS로 탐색을 해주면서
다음 방문할 정점이 1인지 -1인지에 따라
각 수마다 더 큰 수와 작은 수의 개수를 카운트 해주고
모든 정점에 대한 탐색이 끝나면 카운트를 저장해둔 배열을 순회하며
X보다 무겁거나 가벼운 구슬의 개수가 (n+1)/2 이상이면
중간값이 될 수 없다는 것을 알 수 있다.
풀이
public class Main {
private static int n;
private static int next;
private static int[][] near;
private static int[][] count;
private static boolean[] isVisited;
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());
int m = Integer.parseInt(st.nextToken());
near = new int[n + 1][n + 1];
count = new int[n + 1][2];
while (m-- > 0) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
near[x][y] = 1;
near[y][x] = -1;
}
for (int i = 1; i <= n; i++) {
isVisited = new boolean[n + 1];
dfs(i, i, 0);
}
int max = 0;
int mid = (n + 1) / 2;
for (int i = 1; i <= n; i++) {
if(count[i][0] >= mid || count[i][1] >= mid) max++;
}
System.out.println(max);
}
private static void dfs(int start, int cur, int x) {
isVisited[cur] = true;
if(x != 0) count[start][x == 1 ? 0 : 1]++;
for (int i = 1; i <= n; i++) {
next = near[cur][i];
if (isVisited[i] || next == 0) continue;
if (x != 0 && next != x) continue;
dfs(start, i, next);
}
}
}
'Java > Algorithms' 카테고리의 다른 글
[백준] 11725번 : 트리의 부모 찾기 (1) | 2024.01.27 |
---|---|
[백준] 1043번 : 거짓말 (0) | 2024.01.27 |
[백준] 1707번 : 이분 그래프 (1) | 2024.01.24 |
[백준] 2660번 : 회장뽑기 (0) | 2024.01.24 |
[백준] 1260번 : DFS와 BFS (1) | 2024.01.24 |