일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 포스코 ai 교육
- DP
- BFS
- dfs
- 딥러닝
- 삼성코테
- MCU 딥러닝
- 자료구조
- 포스코 교육
- 그리디
- 컴퓨팅사고
- TensorFlow Lite
- 임베디드 딥러닝
- 삼성역테
- 삼성역량테스트
- 알고리즘
- 코딩테스트
- 코테 문제
- 코테
- dfs문제
- tinyml
- 다이나믹프로그래밍
- sort
- 초소형머신러닝
- tflite
- bfs문제
- 삼성코딩테스트
- 포스코 AI교육
- DP문제
- 영상처리
- Today
- Total
코딩뚠뚠
[백준문제풀이] 9466 텀 프로젝트 본문
풀이일시 : 2020-10-13
문제 :
이번 가을학기에 '문제 해결' 강의를 신청한 학생들은 텀 프로젝트를 수행해야 한다. 프로젝트 팀원 수에는 제한이 없다. 심지어 모든 학생들이 동일한 팀의 팀원인 경우와 같이 한 팀만 있을 수도 있다. 프로젝트 팀을 구성하기 위해, 모든 학생들은 프로젝트를 함께하고 싶은 학생을 선택해야 한다. (단, 단 한 명만 선택할 수 있다.) 혼자 하고 싶어하는 학생은 자기 자신을 선택하는 것도 가능하다.
학생들이(s1, s2, ..., sr)이라 할 때, r=1이고 s1이 s1을 선택하는 경우나, s1이 s2를 선택하고, s2가 s3를 선택하고,..., sr-1이 sr을 선택하고, sr이 s1을 선택하는 경우에만 한 팀이 될 수 있다.
예를 들어, 한 반에 7명의 학생이 있다고 하자. 학생들을 1번부터 7번으로 표현할 때, 선택의 결과는 다음과 같다.
1 |
2 |
3 |
4 |
5 |
6 |
7 |
3 |
1 |
3 |
7 |
3 |
4 |
6 |
위의 결과를 통해 (3)과 (4, 7, 6)이 팀을 이룰 수 있다. 1, 2, 5는 어느 팀에도 속하지 않는다.
주어진 선택의 결과를 보고 어느 프로젝트 팀에도 속하지 않는 학생들의 수를 계산하는 프로그램을 작성하라.
입력 :
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫 줄에는 학생의 수가 정수 n (2 ≤ n ≤ 100,000)으로 주어진다. 각 테스트 케이스의 둘째 줄에는 선택된 학생들의 번호가 주어진다. (모든 학생들은 1부터 n까지 번호가 부여된다.)
ex)
2
7
3 1 3 7 3 4 6
8
1 2 3 4 5 6 7 8
출력 :
각 테스트 케이스마다 한 줄에 출력하고, 각 줄에는 프로젝트 팀에 속하지 못한 학생들의 수를 나타내면 된다.
ex)
3
0
풀이 :
dfs를 이용하여 인접노드를 탐색하며 풀이할 수 있는데 1->3->2->1 로 부모가 같아야지 한 팀을 이룰 수 있다.
1->3->2 로 끝나버리면 팀을 이룰수없다.
한 번 방문한 것을 visit으로 나타내는데 다른 팀에서 visit한 노드를 원할 수도 있기 때문에 visit 뿐만 아닌 done배열을 사용한다. done은 완전히 팀을 이룬경우에 1이 되는 배열이다. (visit했다고 끝이아님)
#include <iostream>
#include <cstring> //for memset
#define MAX 100001
using namespace std;
int graph[MAX];
bool visit[MAX];
bool done[MAX]; //더이상 이 노드를 방문하지 않을 것을 확신하는 경우에만 true
int cnt,n;
void dfs(int x) {
visit[x] = true; //방문처리 해주고
int next = graph[x]; //x가 가리키는것이 next
//아예 가리키지 않는다면 끝나버릴것
if (!visit[next]) { //방문 안했다면 dfs를 돌린다
dfs(next);
}
else if (!done[next]) { //done이 0이면
//팀원을 모두 센다
for (int i = next; i != x; i = graph[i]) { //i!=x 라는것은 자기자신이나올때까지
cnt++;
}
cnt++; //자기자신도 더해준다
}
done[x] = true; //x로 시작하는건 더이상 방문하지 않아도 된다는것.
}
int main() {
int T;
cin >> T; //테스트케이스 입력
for (int i = 0; i < T; i++) {
memset(visit, false, sizeof(visit)); //배열을 초기화
memset(done, false, sizeof(done)); //배열을 초기화
cin >> n; //학생의 수
for (int j = 1; j <= n; j++) { //학생의 수만큼 반복
cin >> graph[j]; //그래프에 채운다.
}
cnt = 0;
for (int j = 1; j <= n; j++) {
if (!visit[j]) { //모든 학생노드를 기준으로 visit되지않았다면 dfs돌린다.
dfs(j);
}
}
cout << n - cnt << endl;
}
return 0;
}
'알고리즘 문제풀이 > 백준문제풀이' 카테고리의 다른 글
[백준문제풀이] 2667 단지번호붙이기 (0) | 2021.01.01 |
---|---|
[백준문제풀이] 4963 섬의 개수 (0) | 2021.01.01 |
[백준문제풀이] 11724 연결 요소의 개수 (0) | 2021.01.01 |
[백준문제풀이] 1260 DFS와 BFS (0) | 2020.12.31 |
[백준문제풀이] 1707 이분그래프 (0) | 2020.12.31 |