[코딩테스트 스터디/C++] 여행 계획

1 분 소요

1.문제

임의의 두 여행지 사이에는 양방향 도로가 있다. 여행계획은 여행지의 수 N과 여행 계획에 속한 도시의 수 M으로 이뤄진다. 한울이는 하나의 여행 계획을 세운 뒤에 이 여행 계획이 가능한지의 여부를 판별하는 프로그램을 작성하시오. (1 ≤ N, M ≤ 500)



2. 풀이 전 계획과 생각

  • 서로소 집합 알고리즘 이용



3. 풀이

#include<iostream>
using namespace std;

int n, m;

int map[501][501];
int plan[501];

int parent[501];

// 특정 원소가 속한 집합을 찾기  
int find_parent(int x){
	if(parent[x]!=x) return find_parent(parent[x]);
	return x;
}

// 두 원소가 속한 집합을 합치기  
void union_parent(int a, int b){
	a = find_parent(a);
	b = find_parent(b);
	if(a<b) parent[b]=a;
	else parent[a]=b;
}

int main(){
	// 입력  
	cin>>n>>m;
	
	// 입력  
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) cin>>map[i][j];
	}	
	
	// 입력  
	for(int i=0;i<m;i++) cin>>plan[i];
	
	// 부모테이블에서 부모를 자기 자신으로 초기화  
	for(int i=1;i<=n;i++) parent[i]=i;
	
	// 입력 기반 union연산  
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i<j && map[i][j]==1) union_parent(i,j); 
		}
	}
	
	/*
	for(int i=1;i<=n;i++){
		cout<<find_parent(i)<<endl;
	}
	*/
	
	// 답 찾기  
	bool check=false;
	int check_parent = find_parent(plan[0]);
	for(int i=1;i<m;i++){
		if(check_parent!=find_parent(plan[i])) check=true;
	}
	
	// 답 출력  
	if(check==true) cout<<"NO";
	else cout<<"YES";
}

서로소 집합 알고리즘을 사용 후, 여행지로 입력한 곳이 모두 같은 집합에 속했는지 여부를 체크해, 만약 모두 같은 집합에 속해있으면 “YES”를, 아니면 “NO”를 출력함.



4. 풀이하면서 고민했던 점

  • union연산을 할 때 양방향 그래프라 대각선으로 같은 의미가 있어 이것을 어떻게 처리할지 고민. 대각선을 기준으로 위쪽만 union연산을 함.



5. 문제를 풀고 알게된 개념 및 소감

  • 서로소 집합 알고리즘에 대해 알게됨. 서로소 집합 자료구조 구현과 서로소 집합 알고리즘을 통한 문제해결 법을 알게되었다.