티스토리 뷰
#. Problem
* The copyright in this matter is in BOJ
#. Resolution Process
1. Read and understand problem
2. Redefine the problem + abstract
3. Create solution plan (select Algorithm, Data structure)
4. Prove the plan (check performance time and usage memory)
5. Carry out the plan
6. Look back on the plan and find a way to improve it
#. Solve
우선, 이분 그래프가 무엇인지 알아야 할 것 같다.
나도 이 문제를 풀면서 알게 되었으니..
이분 그래프 : 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있는 그래프.
아래 그림을 보면 바로 이해가 갈 것이다.
이분 그래프의 특징은 자신과 인접해있는 정점과 다른 특성(색 or 값)을 가지고 있다.
이 특성을 이용해서 문제를 풀면 된다.
#. BFS Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #include <cstdio> #include <vector> #include <queue> using namespace std; bool solve() { int v, e, i, j, a, b; scanf("%d %d", &v, &e); vector<vector<int> > vt(v + 1); vector<int> ck(v + 1); queue<int> q; for (i = 0; i < e; i++) { scanf("%d %d", &a, &b); vt[a].push_back(b); vt[b].push_back(a); } for (i = 1; i <= v; i++) { if (ck[i]) continue; q.push(i); ck[i] = 1; while (!q.empty()) { int x = q.front(); q.pop(); for (j = 0; j < vt[x].size(); j++) { if (ck[vt[x][j]] == 0) { ck[vt[x][j]] = ~ck[x] + 1; q.push(vt[x][j]); } else { if (ck[x] + ck[vt[x][j]] != 0) { return false; } } } } } return true; } int main(void) { int tc; // freopen("input.txt", "rt", stdin); scanf("%d", &tc); while (tc--) { if(solve()) printf("YES\n"); else printf("NO\n"); } return 0; } | cs |
line 22~45) 모든 정점을 탐색
line 23) 이미 방문한 정점이면 pass
line 25) 방문하지 않은 정점이면 queue에 넣어주고
line 26) check!
line 28~44) queue가 빌 때까지 반복
line 29~30) queue의 제일 앞에 있는 값을 빼온다
line 32~43) 현재 정점과 연결된 정점들을 탐색
line 33) 연결된 정점이 방문하지 않은 정점이면
line 34) 현재 정점의 ~값에 1을 더해준다.
* 여기서는 시작 노드인 1번 노드의 특성이 1이므로
인접한 정점들은 not 1(-2) + 1 인 -1 이 된다.
반대로 not -1(0) + 1 은 1이 된다.
이렇게 특성이 1인 정점들과 -1인 정점들로 나뉘게 된다.
line 36) 체크해주고 queue에 push!
line 38~42) 연결된 정점이 이미 방문된 정점이면
line 39) 현재 정점과 특성을 비교해서 같으면 false return
(인접한 정점과 특성이 달라야 하는데 같으면 합이 0이 되어버림
특성은 1과 -1로 나뉘어져 있으므로)
* 사실 line 33~37 은 아래 코드처럼 해도 되는데
1 2 3 4 5 6 7 8 | if (ck[vt[x][j]] == 0) { if (ck[x] == 1) ck[vt[x][j]] = -1; else ck[vt[x][j]] = 1; q.push(vt[x][j]); } } | cs |
not(~) 연산자가 이렇게 활용될 수 있는지 몰랐다..
'PS > Problem_Solving' 카테고리의 다른 글
[BOJ] 2331. 반복수열 (0) | 2020.06.25 |
---|---|
[BOJ] 10451. 순열 사이클(DFS, BFS) (0) | 2020.06.24 |
[BOJ] 11724. 연결 요소의 개수(DFS, BFS) (0) | 2020.06.24 |
[BOJ] 1260. DFS와 BFS(DFS, BFS) (0) | 2020.06.24 |
[BOJ] 11052. 카드 구매하기(DP) (0) | 2020.06.22 |