득이공간

[백준 C++] 1976 여행 가자 - 분리집합 본문

PS/알고리즘 문제풀이

[백준 C++] 1976 여행 가자 - 분리집합

쟁득 2024. 2. 1. 16:34
 

1976번: 여행 가자

동혁이는 친구들과 함께 여행을 가려고 한다. 한국에는 도시가 N개 있고 임의의 두 도시 사이에 길이 있을 수도, 없을 수도 있다. 동혁이의 여행 일정이 주어졌을 때, 이 여행 경로가 가능한 것인

www.acmicpc.net

cpp
#include <iostream> #include <vector> using namespace std; vector<int> RootNode; vector<int> Schedule; int Find(int Node) { if (Node == RootNode[Node]) { ‌‌return Node; } return RootNode[Node] = Find(RootNode[Node]); } void Union(int NodeA, int NodeB) { int RootNodeA = Find(NodeA); int RootNodeB = Find(NodeB); int MinRootNode = min(RootNodeA, RootNodeB); ‌RootNode[RootNodeA] = MinRootNode; ‌RootNode[RootNodeB] = MinRootNode; } bool Determine(int NodeA, int NodeB) { return (Find(NodeA) == Find(NodeB)); } int main() { ‌ios::sync_with_stdio(false); ‌cin.tie(NULL); ‌cout.tie(NULL); int N, M; ‌cin >> N >> M; ‌RootNode.reserve(N); for (int i = 0; i < N; ++i) { ‌‌RootNode.emplace_back(i); } for (int i = 0; i < N; ++i) { ‌‌for (int j = 0; j < N; ++j) ‌‌{ ‌‌‌int bLinked; ‌‌‌cin >> bLinked; ‌‌‌if (j < i + 1) ‌‌‌{ ‌‌‌‌continue; ‌‌‌} ‌‌‌if (bLinked == 1) ‌‌‌{ ‌‌‌‌Union(i, j); ‌‌‌} ‌‌} } ‌Schedule.reserve(M); for (int i = 0; i < M; ++i) { ‌‌int City; ‌‌cin >> City; ‌‌Schedule.emplace_back(City - 1); } int Index = 0; for (const int& City : Schedule) { ‌‌if (Index == Schedule.size() - 1) ‌‌{ ‌‌‌break; ‌‌} ‌‌int NextCity = Schedule[Index + 1]; ‌‌if (!Determine(City, NextCity)) ‌‌{ ‌‌‌cout << "NO"; ‌‌‌return 0; ‌‌} ‌‌++Index; } ‌cout << "YES"; }

유니온 파인드 알고리즘을 사용해서 풀었습니다.

 

중복된 유니온 연산을 피하기 위해서 상삼각행렬 부분만 연산을 진행하도록 구현했습니다. (i == j도 제외)

그리고 입력 받은 여행 계획 순서를 배열에 저장한 다음

각 인접 노드끼리 서로 연결되어있는지 확인해서 답을 출력하도록 구현했습니다.