-
[백준] 9466번 텀 프로젝트문제 풀이 2020. 4. 2. 00:05
9466 텀 프로젝트
문제
이번 가을학기에 '문제 해결' 강의를 신청한 학생들은 텀 프로젝트를 수행해야 한다. 프로젝트 팀원 수에는 제한이 없다. 심지어 모든 학생들이 동일한 팀의 팀원인 경우와 같이 한 팀만 있을 수도 있다. 프로젝트 팀을 구성하기 위해, 모든 학생들은 프로젝트를 함께하고 싶은 학생을 선택해야 한다. (단, 단 한 명만 선택할 수 있다.) 혼자 하고 싶어하는 학생은 자기 자신을 선택하는 것도 가능하다.
학생들이(s1, s2, ..., sr)이라 할 때, r=1이고 s1이 s1을 선택하는 경우나, s1이 s2를 선택하고, s2가 s3를 선택하고,..., sr-1이 sr을 선택하고, sr이 s1을 선택하는 경우에만 한 팀이 될 수 있다.
주어진 선택의 결과를 보고 어느 프로젝트 팀에도 속하지 않는 학생들의 수를 계산하는 프로그램을 작성하라.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫 줄에는 학생의 수가 정수 n (2 ≤ n ≤ 100,000)으로 주어진다. 각 테스트 케이스의 둘째 줄에는 선택된 학생들의 번호가 주어진다. (모든 학생들은 1부터 n까지 번호가 부여된다.)
출력
테스트 케이스마다 한 줄에 출력하고, 각 줄에는 프로젝트 팀에 속하지 못한 학생들의 수를 나타내면 된다.
풀이)
재귀적 방법을 통해 사이클이 생겼으면 팀으로 묶는 방법을 사용했다.
처음에 main()에서 각 학생에 대한 재귀 함수를 호출할 때, 학생이 이미 사이클에 속하는지 아닌지 확인했던 걸 체크해주지 않았더니
각 학생마다 재귀를 돌면서, 시간초과가 일어났다.
그래서 이미 확인해봤던 학생은 재귀를 돌지 않게 하면서, 다시 확인하지 않도록 해줬다.
과정은 이러하다.
1. 빈 vector 변수를 만든다.
2. i*번 학생부터 함수를 통해 함께하고 싶은 학생을 확인한다.
3. 만약 함께하고 싶은 학생이 j일때
3.1 j가 이전에 확인했던 학생이 아닌 경우 vector에 넣어주고 j에 대한 재귀적 함수 호출한다. 2
3.2 j가 확인했던 친구라면 vector에서 함수를 처음에 호출했던 학생 번호 i*로 사이클이 생기는 지 확인한다.
사이클 생성되었다면, vector에서 사이클에 포함된 학생을 제외한
나머지 학생의 수를 어느 프로젝트 팀에도 속하지 않는 학생이라고 본다.
코드)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051#include <stdio.h>#include <vector>using namespace std;int n;vector <int> stu;bool visited[100001]; //0, 1~100000vector <int> test;int person;//팀에 속해져있는사람수void dfs(int idx) {if (visited[idx] == false) {test.push_back(idx);visited[idx] = true;dfs(stu[idx]);}else {int i = 0;for (i; i < test.size(); i++) {if (test[i] == idx) break;}person += (test.size() - i);}}int main() {int t;scanf("%d", &t);for (int i = 0; i < t; i++) {scanf("%d", &n);stu.resize(n + 1);for (int j = 1; j <= n; j++) {scanf("%d", &stu[j]);}for (int j = 1; j <= n; j++) {if (visited[j] == false) {dfs(j);test.clear();}}printf("%d\n", n - person);fill(visited, visited + n + 1, false);person = 0;}return 0;}cs 혹시 이해가 되지 않을까봐 문제 예시에 대한 그림을 그려봤다.
7명의 학생이 있고, 선택의 결과가 이러하다면
1 2 3 4 5 6 7 3 1 3 7 3 4 6 결과)
'문제 풀이' 카테고리의 다른 글
[백준] 1107번 리모컨 (0) 2020.04.03 [백준] 1181번 단어정렬 (0) 2020.04.02 [백준] 1182번 부분수열의 합 (0) 2020.04.01 [백준] 1238번 파티 (0) 2020.03.31 [백준] 2533번 사회망서비스 (0) 2020.03.31