개발자 피터
Peter's Dev Blog
개발자 피터
전체 방문자
오늘
어제
  • 분류 전체보기 (77)
    • 🧑🏻‍💻 Develop (13)
      • Devops (3)
      • Elasticsearch (3)
      • Design Pattern (1)
      • SQL (4)
      • Architecture (1)
      • APM (1)
    • 💻 Service (7)
      • E-ROOM (3)
      • Briefing (4)
    • 💡 Problem Solving (43)
      • Baekjoon (40)
      • Programmers (2)
    • 📚 Reading (12)
      • Tech (9)
      • Self-Help (3)
    • 💬 Etc (1)
    • 📈 Retrospective (1)

블로그 메뉴

  • 🌟 깃허브
  • 🏷️ 태그 클라우드
  • 📝 방명록

공지사항

인기 글

태그

  • 구현
  • Programmers
  • 백준
  • 브루트포스
  • MySQL
  • 그리디
  • java
  • boj
  • SQL
  • 문자열
  • elasticsearch
  • E-ROOM
  • 백트래킹
  • briefing
  • 독서

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
개발자 피터

Peter's Dev Blog

💡 Problem Solving/Baekjoon

[백준 - 20040] 사이클 게임 [C++]

2023. 10. 13. 01:16
728x90
반응형

1. 문제

https://www.acmicpc.net/problem/20040

 

20040번: 사이클 게임

사이클 게임은 두 명의 플레이어가 차례대로 돌아가며 진행하는 게임으로, 선 플레이어가 홀수 번째 차례를, 후 플레이어가 짝수 번째 차례를 진행한다. 게임 시작 시 0 부터 n − 1 까지 고유한

www.acmicpc.net

 

2. 풀이

 n개의 점이 있고 m개의 간선 정보가 주어질 때, 몇 번째 간선을 연결했을 때, 사이클이 생기는 지 파악하는 문제이다.

 

방법)

1. 입력된 간선들을 연결할 때마다 DFS를 이용해 정점들에 대해 사이클 여부를 판별해보기 <- O(n * m) 복잡도이므로 무조건 시간초과가 난다.

2. 입력된 간선 (a, b)에 대해 find(a)와 find(b)가 같으면 이전 간선들에 의해 a, b가 연결되어있는 상태이므로 여기서 a와 b를 연결하는 간선을 추가하면 사이클이 생겨버린다. <- Union-find 알고리즘을 활용해 이를 구현해보자

 

3. 코드

#include <iostream>

using namespace std;
int n, m;
int a, b;
int parent[500010];
int ans = -1;

// 20040
/*
    n개의 점이 있고 m개의 간선 정보가 주어질 때,
    몇 번째 간선을 연결했을 때, 사이클이 생기는 지 파악하는 문제이다.

    방법)
    1. 입력된 간선들을 연결할 때마다 DFS를 이용해 정점들에 대해 사이클 여부를 판별해보기 <- O(n * m) 복잡도이므로 무조건 시간초과가 난다.
    2. 입력된 간선 (a, b)에 대해 find(a)와 find(b)가 같으면 이전 간선들에 의해 a, b가 연결되어있는 상태이므로 여기서 a와 b를 연결하는
       간선을 추가하면 사이클이 생겨버린다. <- Union-find 알고리즘을 활용해 이를 구현해보자

*/

int find(int x) {
    if(parent[x] == x) return parent[x]; 
    return parent[x] = find(parent[x]); // 경로 압축.. 이걸 하지 않으면 시간초과..
}

void Union(int x, int y) { // union 예약어가 있어서,, 첫글자를 대문자로..

    int px = find(x);
    int py = find(y);

    if(px != py) parent[px] = py; // x의 부모가 y의 부모를 가리키게 하면 된다.
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    cin >> n >> m;
     
    for(int i=0; i<n; i++) parent[i] = i; // 자기 자신을 루트 노드로 초기화..

    for(int i=1; i<=m; i++) {
        cin >> a >> b;
        if(ans == -1) { // 정답을 아직 못 찾았다면..
            if(find(a) == find(b)) ans = i;
            Union(a, b);
        }
    }

    if(ans == -1) cout << "0";
    else cout << ans;

    return 0;
}

 

728x90
반응형
저작자표시 (새창열림)

'💡 Problem Solving > Baekjoon' 카테고리의 다른 글

[백준 - 15829] Hashing [C++]  (0) 2023.10.14
[백준 - 13335] 트럭 [C++]  (0) 2023.10.14
[백준 - 23247] Ten [C++]  (0) 2023.10.13
[백준 - 1780] 종이의 개수 [C++]  (0) 2021.03.15
[백준 - 1051] 숫자 정사각형 [C++]  (0) 2021.03.14
    '💡 Problem Solving/Baekjoon' 카테고리의 다른 글
    • [백준 - 15829] Hashing [C++]
    • [백준 - 13335] 트럭 [C++]
    • [백준 - 23247] Ten [C++]
    • [백준 - 1780] 종이의 개수 [C++]
    개발자 피터
    개발자 피터
    Backend Engineer 🔥

    티스토리툴바