사이트 링크
개념 및 풀이
유니온파인드를 이용한 문제.
- 진실을 아는 사람들을 같은 그룹으로 묶어줌(union)
- 같은 파티에 있는 사람들을 같은 그룹으로 묶어줌(union)
- 이 과정에서 진실을 아는 사람이 있는 파티는 알아서 진실을 아는 그룹과 같이 될 것임
- 파티를 돌면서 진실을 아는 한 사람과 해당 파티가 같이 묶여있는지 확인
코드
package UnionFind;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main_1043 {
static int N,M,tn,pn,tList[],parents[];
static ArrayList<Integer>[] party;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
makeSet();
st = new StringTokenizer(br.readLine());
tn = Integer.parseInt(st.nextToken());
tList = new int[tn];
for (int i = 0; i < tn; i++) {
tList[i] = Integer.parseInt(st.nextToken());
// 진실을 아는 사람을 한 묶음으로
if(i != 0) union(tList[0],tList[i]);
}
int answer = 0;
if(tn == 0) {
System.out.println(M);
return;
}
party = new ArrayList[M];
boolean[] trueParty = new boolean[M];
for (int m = 0; m < M; m++) {
st = new StringTokenizer(br.readLine());
pn = Integer.parseInt(st.nextToken());
party[m] = new ArrayList<>();
int a = Integer.parseInt(st.nextToken());
party[m].add(a);
for (int i = 1; i < pn; i++) {
int b = Integer.parseInt(st.nextToken());
party[m].add(b);
// 같은 파티에 있는 사람 union
// -> 진실을 아는 사람이 있다면 자연스럽게 같은 묶음으로 됨
union(a,b);
}
}
for (int i = 0; i < M; i++) {
//boolean know = false;
//for (int j = 0; j < tn; j++) {
// // 진실을 아는 사람과 해당 파티의 사람(각 파티 사람들은 모두 같은그룹)이 묶여있는지 확인
// if(party[i].size() != 0 && !know(party[i].get(0),tList[j])) {
// know = true;
// break;
// }
//}
//if(!know) answer++;
if(know(party[i].get(0),tList[0])) {
answer++;
}
}
System.out.println(answer);
}
static boolean know(int a, int b) {
int aRoot = findSet(a);
int bRoot = findSet(b);
if(aRoot == bRoot) return false;
return true;
}
static void makeSet() {
parents = new int[N+1];
for (int i = 1; i <= N; i++) {
parents[i] = i;
}
}
static int findSet(int a) {
if(a==parents[a]) return a;
return parents[a] = findSet(parents[a]);
}
static boolean union(int a,int b) {
int aRoot = findSet(a);
int bRoot = findSet(b);
if(aRoot == bRoot) return false;
parents[bRoot] = aRoot;
return true;
}
}
'공부 > 알고리즘' 카테고리의 다른 글
[프로그래머스]PCCP 기출 2번 Java 풀이(반례 포함) (0) | 2023.10.26 |
---|---|
[백준]9095_1,2,3 더하기_Java 풀이 (0) | 2023.10.25 |
[백준]11724_연결 요소의 개수_BFS Java 풀이(반례 포함) (0) | 2023.09.12 |
[프로그래머스]12914_멀리 뛰기_DP Java 풀이 (0) | 2023.09.06 |
[Java]이진탐색 총 정리(상한upper bound, 하한lower bound, 중복 고려, while문 범위 설정,Arrays.binarySearch()메소드 등) (0) | 2023.05.19 |
댓글