그래프의 정점의 집합을 둘로 분할하여,
각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때,
그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다.
dfs로 정점들을 탐색하며 간선으로 연결된 정점들은 다른 집합에 속하도록 한다.
check[x] == 1 또는 2 // 집합 1 또는 2에 넣기 (0이면 방문 안한 정점)
입력 예제는 성공했지만 계속 4초에서 3초로 넘어가는 중에 실패처리가 나와서 의문이였는데
그래프가 2개 이상의 연결요소로 구성된 경우를 처리하지 않았기 때문이라는 것을 깨달았다.
(그래프의 모든 정점들이 연결되어 있지 않고 섬처럼 떨어져 있을 수도 있다는 것)
import java.util.*;
public class Main {
static ArrayList<Integer>[] graph; // 인접리스트로 그래프 구현
static int[] check; // 각 정점의 방문여부와 소속 집합을 기록 (0:방문안함, 1:집합1, 2:집합2)
static void dfs(int x, int prevGroup) {
if (prevGroup == 1) check[x] = 2;
else if (prevGroup == 2) check[x] = 1;
for (int y : graph[x]) {
if (check[y] == 0) { // 방문 안한 정점이면
dfs(y, check[x]);
}
}
}
static String checkBipartite(int vertex) {
for (int i=1;i<=vertex;i++) { // 모든 정점과 연결된 정점들에 대해 확인
for (int x : graph[i]) { // (모든 간선을 확인)
if (check[i] == check[x]) { // 간선으로 연결된 간선이 같은 집합에 속하면
return "NO"; // 이분 그래프가 아님
}
}
}
return "YES"; // 위 루프를 모두 통과하면 이분 그래프가 맞음
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int cases = sc.nextInt(); // 테스트 케이스 개수
for (int i=0;i<cases;i++) {
int n = sc.nextInt(); // 정점의 개수
int m = sc.nextInt(); // 간선의 개수
graph = (ArrayList<Integer>[]) new ArrayList[n+1]; // 정점의 개수만큼 리스트를 원소로 갖는 배열 생성
for (int j=1;j<=n;j++){
graph[j] = new ArrayList<Integer>(); // 각 정점마다 리스트 생성
}
for (int j=0;j<m;j++) { // 간선 저장
int u = sc.nextInt();
int v = sc.nextInt();
graph[u].add(v);
graph[v].add(u);
}
check = new int[n+1]; // 각 정점에 대한 방문 여부와 집합 기록 배열 생성
// 그래프를 구성하는 연결요소가 2개 이상일 수도 있기 때문에
// dfs 수행하고도 방문하지 않은 정점이 있는지 확인해야 함
for (int j=1; j<=n; j++) {
if (check[j] == 0) {
dfs(j, 1);
}
}
System.out.println(checkBipartite(n));
}
}
}
'알고리즘 > 백준 알고리즘(JAVA)' 카테고리의 다른 글
Java)11576번 Base Conversion (진법 변환) (0) | 2020.09.03 |
---|---|
Java)2089번 -2진수 (0) | 2020.09.03 |
JAVA)11724번 연결 요소의 개수 - 그래프, DFS (0) | 2020.08.19 |
JAVA)DFS와 BFS - 그래프의 구현(인접 리스트), DFS, BFS (0) | 2020.08.19 |
JAVA)10820번 문자열 분석 - Character 클래스의 메소드, eof 처리 (0) | 2020.08.18 |
전체 글
133개JAVA)1707번 이분 그래프 - DFS
그래프의 정점의 집합을 둘로 분할하여, 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때, 그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다. dfs로 정점들을 탐색하며 간선으로 연결된 정점들은 다른 집합에 속하도록 한다. check[x] == 1 또는 2 // 집합 1 또는 2에 넣기 (0이면 방문 안한 정점) 입력 예제는 성공했지만 계속 4초에서 3초로 넘어가는 중에 실패처리가 나와서 의문이였는데 그래프가 2개 이상의 연결요소로 구성된 경우를 처리하지 않았기 때문이라는 것을 깨달았다. (그래프의 모든 정점들이 연결되어 있지 않고 섬처럼 떨어져 있을 수도 있다는 것) import java.util.*; public class Main { static Arr..
알고리즘/백준 알고리즘(JAVA) 2020.08.21 starmk95JAVA)11724번 연결 요소의 개수 - 그래프, DFS
그래프의 연결 요소를 확인하는 방법은 임의의 정점에서 DFS 또는 BFS 탐색을 수행한 후에도 방문하지 않은 정점이 남아있다면, 다른 연결요소가 있다는 특성을 이용한 것이다. 모든 정점들에 대하여 각 정점을 방문했는지 확인하고, 방문하지 않은 정점이 있다면 연결요소의 개수를 1개 추가하고 해당 정점에서 다시 탐색을 수행한다. import java.util.*; public class Main { static ArrayList[] graph; // 인접 리스트로 그래프 구현 static boolean[] check; // 정점 방문 여부 확인하는 배열 static void dfs(int x) { if (check[x]) return; // 이미 방문한 정점이면 해당 정점에서는 탐색 안함 check[x] =..
알고리즘/백준 알고리즘(JAVA) 2020.08.19 starmk95JAVA)DFS와 BFS - 그래프의 구현(인접 리스트), DFS, BFS
리스트(그래프)의 원소(정점) 접근은 for each문을 사용하여 처리한다. (for문과 get()메소드로 인덱스를 사용해 접근하는 것보다 빠르기 때문) 위의 이유에 대해서는 하단 링크 참고 https://starmk95.tistory.com/110 JAVA) 리스트에는 for문 대신 for each 문을 사용하자 ArrayList 자료구조를 예시로 들어 설명하면 ArrayList.get(인덱스) 메소드를 실행하면 내부적으로 해당 인덱스를 찾기 위해 루프가 돌게 된다고 한다. 그렇기 때문에 리스트의 원소에 접근할 때, for ea starmk95.tistory.com 인접 리스트를 사용해 그래프를 구현했고 DFS는 재귀, BFS는 Queue를 통해 구현했다. import java.util.*; publi..
알고리즘/백준 알고리즘(JAVA) 2020.08.19 starmk95JAVA) 리스트에는 for문 대신 for each 문을 사용하자
ArrayList 자료구조를 예시로 들어 설명하면 ArrayList.get(인덱스) 메소드를 실행하면 내부적으로 해당 인덱스를 찾기 위해 루프가 돌게 된다고 한다. 그렇기 때문에 리스트의 원소에 접근할 때, for each문을 사용하지 않고 for문을 사용하여 index를 이용해 get으로 접근하면 이중 루프를 사용한 것이 되어 O(n^2)의 시간이 걸리게 된다. 그러나 애초에 for each문을 사용하여 리스트의 원소에 접근하면 get() 메소드를 사용할 필요가 없으므로 루프를 한번만 사용한 것이 되어 O(n)의 시간이 걸린다. // 리스트를 for문으로 접근할 경우 for (int i=0;i 가시적으로는 for문 루프 1번이지만 실제 동작으로 생각하면 이중 루프이다. // 리스트를 for each문으..
JAVA 2020.08.19 starmk95JAVA)10820번 문자열 분석 - Character 클래스의 메소드, eof 처리
import java.io.*; public class Main { public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String temp; while ((temp = br.readLine()) != null) { // eof 처리 int upper = 0; int lower = 0; int num = 0; int space = 0; for (int i=0;i
알고리즘/백준 알고리즘(JAVA) 2020.08.18 starmk95JAVA)10824번 네 수 - 자료형
문제가 쉬워보이는데 오답률이 높길래 의아해서 풀었다가 나도 틀려서 당황한 문제 문제의 요구사항(조건)을 잘 확인해야 한다는 것을 느낄 수 있는 문제였다. 문제의 포인트는 알맞는 자료형을 사용하는 것 문제에서 주어지는 4개의 자연수의 각 최대 값은 1,000,000 A와 B를 이어붙인 수는 10,000,001,000,000이 되는데, 이는 int 자료형의 범위를 넘어간다. 그러므로 long 자료형을 사용해서 A, B와 C, D가 이어진 수와 그 합을 처리해줘야한다. import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String A = sc.next..
알고리즘/백준 알고리즘(JAVA) 2020.08.18 starmk95JAVA)1918번 후위 표기식 - 스택(Stack)
해당 문제를 해결하기 위해 괄호에 의한 우선 순위 뿐만 아니라 사칙연산의 연산자들 간의 우선 순위도 고려해야 한다. (괄호) > *, / (곱셈, 나눗셈) > +, - (덧셈, 뺄셈) # 알고리즘 모든 수식의 입력들 처리할 때까지 반복 1. 입력이 피연산자(알파벳)이면 바로 출력문에 append() 2. 입력이 열린 괄호 "("이면 바로 출력문에 append() 3. 입력이 + 또는 - 이면 1) 스택이 비어있다면 바로 push() 2) 스택이 비어있지 않다면 계속 pop()하고 append() a) 스택이 비면 중지 b) 열린 괄호 "("를 만나면 중지 a 또는 b 과정 끝나면 입력된 연산자 push 4. 입력이 * 또는 / 이면 1) 스택이 비어있다면 바로 push() 2) 스택이 비어있지 않다면 계..
알고리즘/백준 알고리즘(JAVA) 2020.08.18 starmk95알고리즘) 트리(Tree)
# 트리 : 사이클이 없는 연결 그래프 1. 사이클이 없다 2. 연결되어 있다. 3. 그래프이다. 트리의 정점의 개수 = V, 트리의 간선의 개수 = V-1 (정점이 N개, 간선이 N개면 사이클이 1개만 존재하게 된다.) cf) 트리라고 무조건 루트가 존재하는 것은 아니다. 루트는 정하기에 따라 달라진다. # 트리에서의 부모(parent), 자식(child), 단말 노드(leaf node) 위 예시에서 루트 = 노드 1로 정의했을 때, 노드 1의 자식 = 노드 2, 노드 3 노드 2의 부모 = 노드 1 (루트 노드(노드 1)의 부모는 존재하지 않는다.) 해당 트리의 단말 노드 = 노드 4, 5, 6, 7 노드 2의 형제(sibling) 노드 = 노드 3 # 깊이(Depth) : 루트로부터 노드의 거리 깊..
알고리즘 2020.08.17 starmk95알고리즘) 그래프의 탐색 - DFS, BFS
# 그래프의 탐색의 목적 임의의 정점에서 시작하여 연결되어 있는 모든 정점을 1번씩 방문하는 것 (1번 이상 방문하면 그것은 DFS, BFS가 아님) DFS, BFS는 어떤 순서로 정점을 방문하는 것인가에 차이를 갖는다. # DFS (깊이 우선 탐색) 한 정점에서 시작하여 최대한 깊게 탐색(새로운 연결된 정점이 없을 때까지)하고 더 이상 깊게 탐색할 정점이 없으면 탐색해온 경로를 되돌아오면서 다시 탐색한다. (새로운 정점 : 방문한 적이 없는 정점) (사람 1명이 탐색을 하는 것이라고 비유할 수 있다.) # BFS (너비 우선 탐색) 탐색을 시작한 정점부터 각 정점에서 방문 가능한(연결되어 있는) 모든 새로운 정점들을 1번에 확인하는 방식으로 탐색한다. (사람이 연결된 정점의 수만큼 복제되면서 탐색하는 ..
알고리즘 2020.08.17 starmk95JAVA)13023번 ABCED - 그래프(인접 행렬, 인접 리스트, 간접 리스트)
import java.util.*; class Edge { // 간접 리스트를 위한 클래스 int from, to; Edge(int from, int to) { this.from = from; this.to = to; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // 사람 수 int m = sc.nextInt(); // 관계 수 boolean[][] a = new boolean[n][n]; // 인접 행렬 구현 ArrayList[] g = (ArrayList[]) new ArrayList[n]; // 인접 리스트 구현 ArrayL..
알고리즘/백준 알고리즘(JAVA) 2020.08.17 starmk95알고리즘) 그래프(Graph)
그래프 문제는 문제에 나와 있는 상황을 그래프로 모델링해서 푼다. 어떻게 문제의 상황을 그래프로 만드는지가 관건! # 그래프는 G = (V, E)로 나타낸다. V는 vertex(정점) E는 Edge(간선)의 약자 # 사이클 : 정점 A에서 다시 정점 A로 돌아오는 경오 # 단순 경로, 단순 사이클 (Simple Path, Simple Cycle) - 경로, 사이클에서 같은 정점을 2번 이상 방문하지 않는 경로, 사이클이다 - 일반적으로 경로, 사이클로 적혀있을 경우, 이를 의미한다. # 방향 있는 그래프, 방향 없는 그래프 (Directed/Undirected Graph) - 간선들에 방향이 있으면 directed, 없으면 undirected이다. # 가중치(Weight) - 간선의 값이다. - 주로 간..
알고리즘 2020.08.17 starmk95Retrofit 사용을 위한 Model 추가하기 - Postman, jsonschema2pojo 사용
0. PostMan을 설치하고 New를 통해 새로운 공간을 할당한다. 1. 사용하고자하는 API의 json 출력을 Postman을 통해 받는다. GET으로 받아오는 json 데이터의 출력 결과를 밑의 창으로 확인할 수 있다. (해당 예시는 네이버 영화 검색 API의 출력 결과를 가져온다.) (네이버 api의 경우 Header 데이터로 네이버 api 사용 등록 시에 제공되는 clientId와 clientSecret을 보내야 접근 권한이 주어진다.) 2. http://www.jsonschema2pojo.org/로 이동하여 PostMan을 통해 얻은 json 출력결과를 붙여넣고 조건에 맞게 체크박스를 설정하고 하단의 Zip 버튼을 누른다. (위 설정은 retrofit을 사용하고 gson converter를 사..
Android Studio (모바일 프로그래밍) 2020.08.14 starmk95