https://www.acmicpc.net/problem/1707
1707번: 이분 그래프
입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수 E(1≤E≤200,000)가 빈 칸을 사이에 두고 순서대로 주어진다. 각 정점에는 1부터 V까지 차례로 번호가 붙어 있다. 이어서 둘째 줄부터 E개의 줄에 걸쳐 간선에 대한 정보가 주어지는데, 각 줄에 인접한 두 정점의 번호가 빈 칸을 사이에 두고 주어
www.acmicpc.net
문제를 풀기 위해서 이분 그래프의 개념을 확실하게 알고가야 합니다.
그래프를 두 그룹으로 나누어서 각 그룹이 서로 연결되어 있지 않다면 이분 그래프라고 합니다. 그래서 처음 1번 정점에 시작해서 DFS를 하는데 처음 시작하는 정점을 1로 시작했다면 1과 연결되어 있는 점은 2번으로 표시합니다. 그리고 2번이라고 표시되어 있는 점과 연결되어있는 점들을 1로 표시하여 그래프를 두 그룹으로 나누었습니다.
그럼 최종적으로 표시되는 그래프의 정점들에 저장된 번호들은 1 아니면 2가 저장되어있고, 연결되어있는 점들의 번호를 확인해서 같은 번호가 저장되어있으면 이분그래프가 아닌것으로 판단합니다.
[문제 풀이]
1. ArrayList 배열에 정점과 연결되어 있는 정점들을 저장합니다.
2. visited 배열에는 0, 1, 2가 저장 됩니다. 0 -> 방문하지 않음 / 1 -> 그룹 A / 2 -> 그룹 B
3. 1번 정점부터 DFS(정점 번호, 그룹을 나타내는 숫자) 를 시작합니다. 1번은 임의로 A그룹이라고 시작합니다.
3-1. DFS 의 3-type 부분은 다음 정점은 1, 2를 번갈아가면서 표시하기 위해서 입니다.
4. DFS가 끝나면 visited에 1, 2가 저장되어 있고, 각 정점에서 연결된 정점들에 번호가 같은지 검사합니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
static int K, V, E;
static ArrayList<Integer>[] list;
static int[] visited;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
K = Integer.parseInt(br.readLine());
for(int tc=1; tc<=K; tc++) {
st = new StringTokenizer(br.readLine(), " ");
V = Integer.parseInt(st.nextToken());
E = Integer.parseInt(st.nextToken());
visited = new int[V+1]; // 0:방문x, 1:groupA, 2:groupB
list = new ArrayList[V+1];
for(int i=1; i<=V; i++) list[i] = new ArrayList();
for(int i=0; i<E; i++) {
st = new StringTokenizer(br.readLine(), " ");
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
list[a].add(b);
list[b].add(a);
}
for(int i=1; i<=V; i++) {
if(visited[i] == 0) {
dfs(i, 1);
}
}
boolean flag = true;
Out : for(int i=1; i<=V; i++) {
for(int j : list[i]) {
if(visited[j] == visited[i]) {
flag = false;
break Out;
}
}
}
if(flag) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
public static void dfs(int x, int type) {
visited[x] = type;
for(int i=0; i<list[x].size(); i++) {
int nx = list[x].get(i);
if(visited[nx] == 0) {
dfs(nx, 3-type);
}
}
}
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
[SWEA] 1251. [S/W 문제해결 응용] 4일차 - 하나로 (0) | 2020.04.16 |
---|---|
[SWEA] 9760. Poker Game (2) | 2020.04.03 |
[SWEA] 1244. [S/W 문제해결 응용] 2일차 - 최대 상금 (0) | 2020.03.07 |
[백준] 13460. 구슬 탈출 2 (0) | 2020.03.01 |
[SWEA] 3289. 서로소 집합 (0) | 2020.03.01 |