[백준] 20955번 민서의 응급 수술 (C++)

2025. 8. 12. 14:28·Algorithm
728x90

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

 

 

이 문제는 뉴런이라는 트리가 입력으로 주어질때 

1. 뉴런끼리 연결하는 간선을 추가

2. 뉴런끼리 연결하는 간선을 제거

 

두 가지 행동을 최소로 사용해 하나의 뉴런으로 만드는 횟수를 출력하는 문제이다.

 

 

위 그림처럼 간선을 추가하는 경우는 하나의 트리가 아닌 여러개의 트리가 존재할때

그 트리들을 하나로 연결하기 위해서는 트리의 개수 -1 개의 간선 추가가 필요하다.

 

하지만 간선을 제거하는 경우는 사이클이 존재하는 트리가 주어질 때 

사이클을 제거하기 위해서 간선을 제거해야한다.

 

즉 점화식은 트리의 개수 + 사이클 개수 - 1이 된다.

 

따라서 유니온 파인드(분리 집합)을 사용하여 입력으로 들어오는 간선을 비교하여 같은 노드에 있는지 확인하며

만약 같은 노드에 있는 경우는 사이클이 존재한다는 것이므로 사이클 개수를 추가해준다.

 

이후 set에 부모 노드를 넣어줌으로써 트리의 개수를 알 수 있기 때문에

set의 크기 + 사이클 개수 - 1을 해주었다.

 

정답 코드

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"
#define MAX 1e9

struct coordinate {
    int x;
    string s;
    vector<int> v;
};

int dx[] = {-1, 0, 1, 0, 1, -1, -1, 1};
int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};
int N, M;
int unf[100001];
set<int> st;
int cycle;

int Find(int a) {
    if(a == unf[a]) return a;
    return unf[a] = Find(unf[a]);
}

void Union(int a, int b) {
    a = Find(a);
    b = Find(b);

    if(a > b) unf[a] = b;
    else unf[b] = a;
}

bool isUnion(int a, int b) {
    a = Find(a);
    b = Find(b);

    if(a == b) return true;
    else return false;
}

void Init() {
    for(int i = 1; i <= N; i++) {
        unf[i] = i;
    }
}

void solve() {
    for(int i = 1; i <= N; i++) {
        st.insert(Find(i));
    }

    cout << cycle + st.size()-1;
}

void input() {
    cin >> N >> M;

    Init();

    for(int i = 0; i < M; i++) {
        int a, b;
        cin >> a >> b;
        if(!isUnion(a, b)) {
            Union(a, b);
        }
        else {
            cycle++;
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();
}

 

 

회고록

처음에 문제를 보고 트리인 것을 보고 무조건 dfs를 사용해야 할것 같았다. 그래서 dfs를 사용하여

사이클이 존재하는지 유무를 판별하고 개수를 증가시키고 트리의 개수를 세주었는데

중간에 계속 틀려서 질문 게시판을 보고 몇개의 반례에서 통과하지 못하는 것을 알았다...

 

결국 분류를 보니 유니온 파인드로 풀 수 있는것을 보고 바로 풀었는데 이런점에서 약간 부족한것 같다

강한 확신이 오히려 독이 된다는 느낌이다..

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

'Algorithm' 카테고리의 다른 글

[백준] 16940번 BFS 스페셜 저지 (C++)  (0) 2025.08.14
[백준] 1766번 문제집 (C++)  (0) 2025.08.13
[백준] 15900번 나무탈출 (C++)  (0) 2025.08.11
[백준] 1726번 로봇 (C++)  (0) 2025.08.10
[백준] 13901번 로봇 (C++)  (0) 2025.08.09
'Algorithm' 카테고리의 다른 글
  • [백준] 16940번 BFS 스페셜 저지 (C++)
  • [백준] 1766번 문제집 (C++)
  • [백준] 15900번 나무탈출 (C++)
  • [백준] 1726번 로봇 (C++)
쿨쿨.
쿨쿨.
  • 쿨쿨.
    All of the life
    쿨쿨.
  • 전체
    오늘
    어제
    • 분류 전체보기 (286) N
      • Programming (53) N
        • C, C++ (18)
        • Python (6)
        • Java (1)
        • HTML,CSS,JS (3)
        • SQL(DB) (13)
        • SpringBoot (9) N
        • Android (2)
        • CI,CD (1)
      • Algorithm (173)
        • Review (4)
      • Security (14)
        • WebHacking (3)
        • Websecurity (11)
      • OS (19)
        • Linux (12)
        • Mac os (2)
      • 머신러닝 (1)
      • CS(Computer Science) (12)
        • 컴퓨터 네트워크 (3)
        • 컴퓨터 구조 (1)
        • 인공지능 (8)
      • Docker (2) N
      • Dev Book Review (3)
        • Clean Code (1)
        • Effective Java (0)
        • Real MySQL (2)
      • SWM (1)
      • Review (6)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코딩
    구현
    에라토스테네스의 체
    정렬
    그래프 이론
    트리
    linux
    Leviathan
    WebSecurity
    DP
    비트마스킹
    Bandit
    DFS
    다이나믹 프로그래밍
    백트래킹
    재귀
    투포인터
    wargame
    깊이우선탐색
    다익스트라
    우선순위큐
    그리디
    이분탐색
    누적합
    우선순위 큐
    브루트포스
    시뮬레이션
    c언어
    BFS
    백준
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.6
쿨쿨.
[백준] 20955번 민서의 응급 수술 (C++)
상단으로

티스토리툴바