백준[3830] 교수님은 기다리지 않는다
2021. 11. 12. 02:05
Algorithm/BOJ
문제 링크 http://icpc.me/3830 3830번: 교수님은 기다리지 않는다 교수님의 질문 (? a b)이 입력으로 들어올 때 마다, 지금까지 측정한 결과를 바탕으로 a와 b의 무게 차이를 계산할 수 있다면, b가 a보다 얼마나 무거운지를 출력한다. 무게의 차이의 절댓값이 1,000, www.acmicpc.net 풀이 유니온 파인드를 이용하여 풀었다. 대소 관계를 이용하여 무게 차이를 구할 수 있는 것들을 같은 집합으로 묶는다. 이때, dist 배열에 두 개의 무게 차를 저장해 놓는다. dist 배열의 정의는 dist [i]는 i와 i의 부모의 거리이다. 또한 두 집합의 루트 사이의 거리를 정의해줘야 하는데, a, b를 union 할 때 a의 루트를 pa, b의 루트를 pb라고 하면, dist [..
백준[1043] 거짓말
2021. 11. 8. 14:30
Algorithm/BOJ
문제 링크 http://icpc.me/1043 1043번: 거짓말 지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게 www.acmicpc.net 풀이 유니온 파인드를 이용해서 풀 수 있다. 진실을 아는 사람들을 같은 집합에 넣어두고, 파티 구성원들을 같은 집합에 넣을 때, 만약 이 집합에 진실을 아는 사람들이 있다면 진실을 아는 사람 그룹에 그 파티 구성원들을 모두 넣어야 한다. 그 후에 파티 구성원들 집합을 확인하며 진실을 모르는 사람들만 모여있는 집합의 개수를 세면 된다. 코드 #include #include #include using namespace std; i..
백준[4013] ATM
2021. 7. 30. 16:28
Algorithm/BOJ
문제 링크 https://www.acmicpc.net/problem/4013 풀이 SCC, 유니온 파인드, 위상 정렬, dp를 이용하여 풀이하였다. 다 푼 후에 다른 사람의 코드를 보고 깨달았지만, 유니온 파인드는 굳이 사용하지 않아도 된다. 출발지점부터 순회하며 dp를 돌리면 될 것 같지만 사이클이 존재하기 때문에 그럴 수 없다. 그렇기 때문에 사이클이 없는 방향 그래프로 바꿔줘야 한다. 사이클을 제거하기 위해 SCC를 사용한다. 아래 코드는 코사라주 알고리즘을 이용하였다. 구해진 SCC를 이용하여 사이클을 하나의 큰 노드로 합친다. 나는 이때 유니온 파인드를 사용하였다. 하지만 이미 SCC들을 모두 구했기 때문에 이미 합쳐져 있는 상태여서 유니온 파인드를 사용하지 않아도 된다. scc vector의 ..
백준[2162] 선분 그룹
2021. 6. 30. 20:19
Algorithm/BOJ
풀이 이 문제는 ccw와 union find를 이용하여 해결 할 수 있다. 두 직선이 교차되었는지 판별은 선분 교차2와 동일하다. 모든 선분들에 대해 서로 교차되었는지 판변하고 교차되었다면 union을 한다. ccw의 리턴값을 1 -1 0이 아닌 원래 값으로 리턴하여, check함수에서 두 값을 곱할 시 오버플로우가 발생할 것을 예상하지 못하고 맞왜틀을 외쳤다. 조심하도록 하자. 코드 #include #include #define x first #define y second using namespace std; using pii = pair; pii a[3003], b[3003]; int par[3003], member_size[3003]; int ccw(pii a, pii b, pii c) { int ..
백준[20040] 사이클게임
2021. 6. 21. 23:26
Algorithm/BOJ
풀이 방법 유니온 파인드라는 자료구조를 이용하여 풀이하였다. 입력받은 두개의 루트 노드가 같으면 사이클이 형성되었다고 판단하고, 다르다면 두개의 트리를 합친다. 코드 #include #include using namespace std; int par[500005], level[500005]; int find(int x) { if (x == par[x]) return x; return par[x] = find(par[x]); } void merge(int x, int y) { int a = find(x), b = find(y); if (a == b) return; if (level[a] > level[b]) swap(a, b); if (level[a] == level[b]) level[b]++; par[a..