일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- iOS14
- c++
- scanf
- 입출력 패턴
- Django Nodejs 차이점
- double ended queue
- 프레임워크와 라이브러리의 차이
- Django의 편의성
- 엑셀
- 알고리즘 공부방법
- 자료구조
- 매크로
- k-eta
- 백준
- 연결요소
- 구조체와 클래스의 공통점 및 차이점
- string 함수
- 이분그래프
- 시간복잡도
- 표준 입출력
- correlation coefficient
- UI한글변경
- vscode
- 2557
- 입/출력
- getline
- EOF
- 장고란
- string 메소드
- Django란
Archives
- Today
- Total
Storage Gonie
(6) [C++] 백준 No.9466 : 텀 프로젝트 본문
반응형
문제
풀이
자세한 풀이 : https://ldgeao99.tistory.com/398
# C++(재귀적 구현)
#include<iostream>
#include<cstring>
using namespace std;
int arr[100001]; // 인접리스트
int check[100001]; // 방문유무 및 방문순서를 저장하는 check 배열
int which_search[100001]; // 몇번째로 진행되는 탐색의 경로에 포함되는지 저장하는 배열
// 함수가 한번 호출되면 이미 방문한 정점을 찾을 때 까지 진행됨 => 이것이 가능한 이유는 모든 정점이 다음 정점을 가지기 때문에 가능함.
int dfs(int node, int cnt, int &step)
{
// 이미 방문한 곳을 재방문하려고 한다면 이것이 사이클인지 확인해줘야 함
if (check[node] != 0){
if(which_search[node] != step)
return 0;
else
return cnt - check[node];
}
// 첫 방문이라면 방문순서 및 몇번째로 진행되는 탐색인지 기록, 후 다음정점 탐색 진행
else{
check[node] = cnt;
which_search[node] = step;
int next = arr[node];
return dfs(next, cnt+1, step);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t;
cin >> t;
while(t--){
// 데이터 입력받기 및 초기화
int n;
cin >> n;
for(int i = 1; i <= n; i++)
cin >> arr[i];
memset(check, 0, sizeof(check));
memset(which_search, 0, sizeof(which_search));
// 시작점을 바꿔가며 탐색을 진행하면서 발견되는 사이클의 크기를 합함
int ans = 0;
for (int i = 1; i <= n; i++ )
ans += dfs(i, 1, i);
// 결과 = 총 학생수 - 팀을 이룬 학생수
cout << n-ans << "\n";
}
}
# C++(비재귀적 구현)
#include<iostream>
#include<cstring>
using namespace std;
int arr[100001]; // 인접리스트
int check[100001]; // 방문유무 및 방문순서를 저장하는 check 배열
int which_search[100001]; // 몇번째로 진행되는 탐색의 경로에 포함되는지 저장하는 배열
// 함수가 한번 호출되면 이미 방문한 정점을 찾을 때 까지 진행됨 => 이것이 가능한 이유는 모든 정점이 다음 정점을 가지기 때문에 가능함.
int dfs(int node, int cnt, int &step)
{
while(check[node] == 0){
check[node] = cnt;
which_search[node] = step;
cnt += 1;
node = arr[node];
}
if (step == which_search[node])
return cnt - check[node];
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t;
cin >> t;
while(t--){
// 데이터 입력받기 및 초기화
int n;
cin >> n;
for(int i = 1; i <= n; i++)
cin >> arr[i];
memset(check, 0, sizeof(check));
memset(which_search, 0, sizeof(which_search));
// 시작점을 바꿔가며 탐색을 진행하면서 발견되는 사이클의 크기를 합함
int ans = 0;
for (int i = 1; i <= n; i++ )
ans += dfs(i, 1, i);
// 결과 = 총 학생수 - 팀을 이룬 학생수
cout << n-ans << "\n";
}
}
# C++(재귀적 구현, cnt 1부터 쭉 증가시키기)
#include<iostream>
#include<cstring>
using namespace std;
int arr[100001]; // 인접리스트
int check[100001]; // 방문유무 및 방문순서를 저장하는 check 배열
int which_search[100001]; // 몇번째로 진행되는 탐색의 경로에 포함되는지 저장하는 배열
// 함수가 한번 호출되면 이미 방문한 정점을 찾을 때 까지 진행됨 => 이것이 가능한 이유는 모든 정점이 다음 정점을 가지기 때문에 가능함.
int dfs(int node, int &cnt, int &step)
{
// 이미 방문한 곳을 재방문하려고 한다면 이것이 사이클인지 확인해줘야 함
if (check[node] != 0){
if(which_search[node] != step)
return 0;
else
return cnt - check[node];
}
// 첫 방문이라면 방문순서 및 몇번째로 진행되는 탐색인지 기록, 후 다음정점 탐색 진행
else{
check[node] = cnt;
which_search[node] = step;
int next = arr[node];
cnt += 1;
return dfs(next, cnt, step);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t;
cin >> t;
while(t--){
// 데이터 입력받기 및 초기화
int n;
cin >> n;
for(int i = 1; i <= n; i++)
cin >> arr[i];
memset(check, 0, sizeof(check));
memset(which_search, 0, sizeof(which_search));
// 시작점을 바꿔가며 탐색을 진행하면서 발견되는 사이클의 크기를 합함
int ans = 0;
int cnt = 1;
for (int i = 1; i <= n; i++ )
ans += dfs(i, cnt, i);
// 결과 = 총 학생수 - 팀을 이룬 학생수
cout << n-ans << "\n";
}
}
반응형
'알고리즘 > 백준풀이9. 그래프' 카테고리의 다른 글
(8) [C++, Java] 백준 No.4963 : 섬의 개수 (0) | 2019.06.01 |
---|---|
(7) [C++, Java] 백준 No.2667 : 단지번호붙이기 (0) | 2019.05.31 |
(5) [C++, Java] 백준 No.2331 : 반복수열 (0) | 2019.05.30 |
(4) [C++, Java] 백준 No.10451 : 순열 사이클 (0) | 2019.05.30 |
(3) [C++, Java] 백준 No.1707 : 이분 그래프 (0) | 2019.05.29 |
Comments