Coding Test/백준
[백준] 4803 트리 - 자바
lsh2613
2023. 9. 16. 15:32
https://www.acmicpc.net/problem/4803
4803번: 트리
입력으로 주어진 그래프에 트리가 없다면 "No trees."를, 한 개라면 "There is one tree."를, T개(T > 1)라면 "A forest of T trees."를 테스트 케이스 번호와 함께 출력한다.
www.acmicpc.net
문제 풀이
그래프이 정보가 주어지고 그래프의 존재하는 트리의 개수를 출력 형식에 맞게 출력해주는 문제이다.
트리의 성립 조건은 문제에도 잘 나와있어 그래프를 저장하고 그래프 안에서 트리에 해당하는 간선과 정점이 개수만 구한다면 쉽게 해결할 수 있다.
그래프 정보 저장
int testCase = 0;
while (true) {
testCase++;
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
if (N==0 && M==0) break;
//init
visit = new boolean[N + 1];
graph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
graph[from].add(to);
graph[to].add(from);
}
트리 갯수 구하기
// tree 갯수 구하기
int treeCnt = 0;
for (int i = 1; i <= N; i++) {
if (visit[i]) continue;
treeVertexCnt = 0;
treeEdgeCnt = 0;
dfs(i);
// 트리 성질: 간선 = (정점-1) * 2
if (treeEdgeCnt == (treeVertexCnt - 1) * 2)
treeCnt++;
}
dfs를 통해 해당 노드를 포함하는 트리의 정점과 간선의 개수를 구해야 한다.
dfs
static int treeVertexCnt;
static int treeEdgeCnt;
static void dfs(int idx) {
treeVertexCnt++;
treeEdgeCnt += graph[idx].size();
visit[idx] = true;
for (int adj : graph[idx]) {
if (visit[adj]) continue;
dfs(adj);
}
}
출력
// 출력 형식 저장
sb.append("Case " + testCase + ": ");
switch (treeCnt) {
case 0:
sb.append("No trees.\n");
break;
case 1:
sb.append("There is one tree.\n");
break;
default:
sb.append("A forest of " + treeCnt + " trees.\n");
}
코드
package 백준;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class b4803 {
static List<Integer>[] graph;
static boolean[] visit;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int testCase = 0;
while (true) {
testCase++;
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
if (N==0 && M==0) break;
//init
visit = new boolean[N + 1];
graph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
graph[from].add(to);
graph[to].add(from);
}
// tree 갯수 구하기
int treeCnt = 0;
for (int i = 1; i <= N; i++) {
if (visit[i]) continue;
treeVertexCnt = 0;
treeEdgeCnt = 0;
dfs(i);
// 트리 성질: 간선 = (정점-1) * 2
if (treeEdgeCnt == (treeVertexCnt - 1) * 2)
treeCnt++;
}
// 출력 형식 저장
sb.append("Case " + testCase + ": ");
switch (treeCnt) {
case 0:
sb.append("No trees.\n");
break;
case 1:
sb.append("There is one tree.\n");
break;
default:
sb.append("A forest of " + treeCnt + " trees.\n");
}
}
System.out.println(sb);
}
static int treeVertexCnt;
static int treeEdgeCnt;
static void dfs(int idx) {
treeVertexCnt++;
treeEdgeCnt += graph[idx].size();
visit[idx] = true;
for (int adj : graph[idx]) {
if (visit[adj]) continue;
dfs(adj);
}
}
}