Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

55-tgyuuAn #189

Merged
merged 2 commits into from
May 22, 2024
Merged

55-tgyuuAn #189

merged 2 commits into from
May 22, 2024

Conversation

tgyuuAn
Copy link
Member

@tgyuuAn tgyuuAn commented May 17, 2024

πŸ”— 문제 링크

친ꡬ λ„€νŠΈμ›Œν¬

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

40λΆ„

✨ μˆ˜λ„ μ½”λ“œ

image

image

μ•Œκ³ λ¦¬μ¦˜ 미리보기 λ°©μ§€μš© λž«μ„œνŒ¬λ” μž…λ‹ˆλ‘₯




μ„ ν–‰μ μœΌλ‘œ μ•Œκ³ λ¦¬μ¦˜ λ…ΈνŠΈ 에 μžˆλŠ” μ„œλ‘œμ†Œ 집합 κ°œλ…μ„ μ•Œκ³  μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

(ν”νžˆ μœ λ‹ˆμ˜¨ νŒŒμΈλ“œλΌκ³  λΆ€λ¦…λ‹ˆλ‹€.)

μœ λ‹ˆμ˜¨ νŒŒμΈλ“œ κ°œλ…μ„ λͺ¨λ₯΄λ©΄ ν’€ 수 μ—†μŠ΅λ‹ˆλ‹€....!

μœ„μ— μ•Œκ³ λ¦¬μ¦˜ λ…ΈνŠΈ λ³΄μ‹œκ³  μΆ”μ²œ 문제λ₯Ό 풀어보신 뒀에 이 문제λ₯Ό ν’€μ–΄λ³΄μ‹œκΈ°λ₯Ό μΆ”μ²œλ“œλ¦½λ‹ˆλ‹€!




κΈ°μ‘΄ μœ λ‹ˆμ˜¨ νŒŒμΈλ“œκ°€ 인덱슀둜 λΆ€λͺ¨ 항을 νŒλ³„ν–ˆλ”λΌλ©΄,

이 λ¬Έμ œλŠ” 해쉬 κ°’μœΌλ‘œ λΆ€λͺ¨λ₯Ό νŒλ³„ν•©λ‹ˆλ‹€.

κ·Έ κ²ƒλ§κ³ λŠ” λ”±νžˆ 더 μ–΄λ €μš΄ 뢀뢄은 μ—†μŠ΅λ‹ˆλ‹€.




μ²˜μŒμ— μ•„λž˜μ™€ 같이 λΆ€λͺ¨ 정보가 μžˆλ‹€κ³  ν•΄λ΄…μ‹œλ‹€.

λ‹Ήμ—°νžˆ μ΄ˆκΈ°μ—λŠ” 정보가 μ—†μœΌλ‹ˆ λΉ„μ–΄μžˆμ„ 것 μž…λ‹ˆλ‹€.

image







κ·Έ λ‹€μŒμœΌλ‘œ Barney와 Fredκ°€ μΉœκ΅¬λΌλŠ” 정보가 μ£Όμ–΄μ‘ŒμŠ΅λ‹ˆλ‹€.

λ‘˜ 쀑에 ν•˜λ‚˜λ₯Ό κΈ°μ€€μœΌλ‘œ λΆ€λͺ¨ 정보λ₯Ό κ°±μ‹ μ‹œμΌœ μ€λ‹ˆλ‹€.

(이 λ•Œ λŒ€λΆ€λΆ„μ˜ μ–Έμ–΄μ—μ„œλ„ λ¬Έμžμ—΄λ„ min ν˜Ήμ€ maxκ°€ 먹힐 것 μž…λ‹ˆλ‹€.)

image







κ·Έ λ‹€μŒμœΌλ‘œ Barney와 Bettyκ°€ μΉœκ΅¬λΌλŠ” 정보가 또 λ“€μ–΄μ˜΅λ‹ˆλ‹€.

그럼 μ•„λž˜ 그림처럼 될 것 μž…λ‹ˆλ‹€.

image







λ§ˆμ§€λ§‰μœΌλ‘œ wilma와 Bettyκ°€ μΉœκ΅¬λΌλŠ” 정보가 λ“€μ–΄μ˜΅λ‹ˆλ‹€.

그럼 μ•„λž˜ 그림처럼 될 것 μž…λ‹ˆλ‹€.

image




이 λ•Œ, 각 친ꡬ 정보가 μ£Όμ–΄μ‘Œμ„ λ•Œ 두 μ‚¬λžŒμ˜ 친ꡬ λ„€νŠΈμ›Œν¬μ— λͺ‡ λͺ…이 μžˆλŠ” 지 μ–΄λ–»κ²Œ κ΅¬ν•˜λŠλƒ ?

맀번 union-findλ₯Ό ν•  λ•Œ λ§ˆλ‹€ λͺ¨λ“  항을 λ’€μ Έλ³Ό 경우 μ‹œκ°„ μ΄ˆκ³Όκ°€ λ‚©λ‹ˆλ‹€




μ–΄λ–»κ²Œ μ•Œμ•˜λƒκ³ μš”?







저도 μ•Œκ³  싢지 μ•Šμ•˜μ–΄μš”.

image







κ·Έλ ‡κΈ° λ•Œλ¬Έμ— 각 λΆ€λͺ¨ λ…Έλ“œλ₯Ό κΈ°μ€€μœΌλ‘œ λͺ‡ λͺ…μ˜ 친ꡬ λ„€νŠΈμ›Œν¬κ°€ ν˜•μ„±λ˜μ–΄ μžˆλŠ” 지λ₯Ό 미리 계산을 ν•΄ 놓아야 ν•©λ‹ˆλ‹€.

주석은 μ„±ν›ˆλ‹˜μ„ μœ„ν•΄ μ¨λ†“μ•˜μ–΄μš”.

for _ in range(T):
    F = int(input())
    index = 1
    parent = defaultdict(str)

    # 해쉬 맡에 처음 λ“€μ–΄κ°ˆ λ•Œ 값을 1둜 μ„€μ •ν•˜λŠ” μ½”λ“œ μž…λ‹ˆλ‹€.
    count = defaultdict(lambda : 1)
    
    for _ in range(F):
        first, second = input().split()
        
        # λ§Œμ•½ 해쉬 맡에 처음 λ“€μ–΄κ°€λŠ” 값일 경우 λΆ€λͺ¨ λ…Έλ“œλ₯Ό 자기 μžμ‹ μœΌλ‘œ μ„€μ •ν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€.
        if parent[first] == "": parent[first] = first                          
        if parent[second] == "": parent[second] = second
     
        if parent[first] != parent[second]: union(first, second, parent, count)

μœ„ μ½”λ“œμ²˜λŸΌ 초기 항이 λ“€μ–΄κ°ˆ λ•Œ count에 각 λ…Έλ“œκ°€ 1둜 μ„€μ •λ˜κ²Œ ν•œ λ‹€μŒ,







union κ³Όμ •μ—μ„œ μžμ‹ λ…Έλ“œμ˜ count 값을 λΆ€λͺ¨ λ…Έλ“œμ˜ count둜 병합 μ‹œμΌœμ£Όλ©΄ λ©λ‹ˆλ‹€.

def union(first, second, graph, count):
    x = find_parent(first, graph)
    y = find_parent(second, graph)

    if x == y: return

    x, y = min(x, y), max(x, y)
    graph[y] = x
    count[x] += count[y]
    count[y] = 0
    return

이러면 맀 λ‹¨κ³„λ§ˆλ‹€ 일일이 λͺ¨λ“  λ…Έλ“œλ₯Ό 탐색할 ν•„μš”κ°€ μ—†μ–΄μ Έμš”!

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

@tgyuuAn tgyuuAn added tgyuuAn ν•œ μ€„λ‘œλŠ” μ†Œκ°œν•  수 μ—†λŠ” λ‚¨μž. μž‘μ„± 쀑 ⏱️ labels May 17, 2024
@tgyuuAn tgyuuAn self-assigned this May 17, 2024
@tgyuuAn tgyuuAn marked this pull request as ready for review May 17, 2024 17:28
Copy link

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

각 트리(집합)의 무게(크기)λ₯Ό μ €μž₯ν•˜λŠ” 것이 비단 이 문제만의 ν‚€λŠ” μ•„λ‹ˆκΈ΄ ν•©λ‹ˆλ‹€.
union-find μ•Œκ³ λ¦¬μ¦˜μ„ μ΅œμ ν™”ν•˜λŠ” 2가지 방법이 μžˆλŠ”λ°, ν•˜λ‚˜κ°€ 잘 μ•Œλ €μ§„ "Path-Compression"이고 λ‹€λ₯Έ ν•˜λ‚˜κ°€ 이 λ¬Έμ œμ—μ„œ 쓰인 "Weighted Union" μž…λ‹ˆλ‹€.
톡상적인 union-find λ¬Έμ œλ“€μ€ path-compression만 μ μš©μ‹œμΌœλ„ μ–΄μ§€κ°„ν•˜λ©΄ μ‹œκ°„ λ¬Έμ œκ°€ λ‹€ ν•΄κ²°λ©λ‹ˆλ‹€λ§Œ.... ν•œ λ²ˆμ―€μ€ κ·Έλž˜λ„ ν™•μΈν•΄λ†“λŠ” 것도 쒋을 것 κ°™μ•„μš” :)

Copy link
Collaborator

@H0ngJu H0ngJu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μœ λ‹ˆμ˜¨ νŒŒμΈλ“œ..... 처음 λ΄€μ–΄μš” ν—ˆν—ˆ
이번 κΈ°νšŒμ— κ³΅λΆ€ν•˜κ³  κ°‘λ‹ˆλ‹· ~! ~!

이 문제 ν’€κΈ° 전에 λ‹€λ₯Έ μ‰¬μš΄ 예제 ν’€λ €κ³  μ°Ύμ•„λ΄€λŠ”λ° λ‹€ κ³¨λ“œ 문제 λΏμ΄λ„€μš” 쩝...
λ‹€λ₯Έ λ¬Έμ œλ“€λ„ λ„μ „ν•΄λ³΄κ² μŠ΄λ‹€
μœ λ‹ˆμ˜¨ νŒŒμΈλ“œ

μˆ˜κ³ ν•˜μ…¨μŠ΄λ‹€ ~~ 😎πŸ’ͺ

import sys
from collections import defaultdict

def input(): return sys.stdin.readline().rstrip()

def find(x): # λΆ€λͺ¨ μ°ΎκΈ°
    if parent[x] != x: # 계속 거슬러 μ˜¬λΌκ°€κΈ°
        parent[x] = find(parent[x])
    return parent[x]


def union(a, b):
    a = find(a)
    b = find(b)

    if a != b:
        parent[b] = a
        network[a] += network[b]
    return network[a]


for _ in range(int(input())):
    num = int(input())
    parent = defaultdict(str)
    network = defaultdict(lambda : 1)

    for i in range(num):
        a, b = input().split()
        if a not in parent: # λΆ€λͺ¨μ— λ“±λ‘λ˜μ§€ μ•Šμ€ 경우
            parent[a] = a
        if b not in parent:
            parent[b] = b
        print(union(a, b)) # 친ꡬ 관계 ν•©μΉ˜κΈ°

Comment on lines +20 to +22
graph[y] = x
count[x] += count[y]
count[y] = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ν˜Ήμ‹œ ν•©μΉ˜λŠ” κ³Όμ •μ—μ„œ count[y]λ₯Ό μ΄ˆκΈ°ν™” ν•΄μ£ΌλŠ” μ΄μœ κ°€ μžˆλ‚˜μš”??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@H0ngJu

왠지 ν•œλ²ˆ λΆ€λͺ¨ λ…Έλ“œλ‘œ λ³‘ν•©λœ μΉœκ΅¬λ“€μ΄ 좔후에 λ‹€μ‹œ μ‚¬μš©λ  것 κ°™λ‹€λŠ” 생각이 λ“€μ–΄μ„œ μ΄ˆκΈ°ν™”λ₯Ό ν–ˆλŠ”λ° 그럴 κ²½μš°λŠ” μ—†λ‚˜μš” ...?

μ € 쀄 빼도 ν†΅κ³Όν•˜κΈ΄ ν•˜λ„€μš” ,,,

F = int(input())
index = 1
parent = defaultdict(str)
count = defaultdict(lambda : 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ΄λ ‡κ²Œ defaultκ°’ 지정이 λ˜λŠ”κ΅°μš”

network[a] = 1

둜 ν–ˆλ‹€κ°€ λ°”λ‘œ μˆ˜μ •ν–ˆμŠ΅λ‹ˆλ‹€ γ…Žγ……γ…Ž

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@H0ngJu 🫑🫑🫑

Copy link
Collaborator

@SeongHoonC SeongHoonC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ–΄.. μ œκ°€ ν‘Όκ²Œ union find κ°€ λ§žλŠ”μ§€λŠ” λͺ¨λ₯΄κ² λŠ”데 λΉ„μŠ·ν•˜κ²Œ ν‘Ό 것 κ°™μ•„μš”!
head λ₯Ό μ°Ύμ•„μ„œ κ·Έ head끼리 λΉ„κ΅ν•΄μ„œ 더 μž‘μ€ κ²ƒμœΌλ‘œ count λ³‘ν•©ν•©λ‹ˆλ‹€.
μ„€λͺ…ν•˜κ³  λ³΄λ‹ˆκΉ λ˜‘κ°™μ€ 것 같은데 제 μ½”λ“œκ°€ 쑰금 λ³΅μž‘ν•˜λ„€μš©..!

import java.io.BufferedReader
import java.io.InputStreamReader

private lateinit var br: BufferedReader
fun main() {
    br = BufferedReader(InputStreamReader(System.`in`))
    val t = br.readLine().toInt()
    repeat(t) {
        makeNetwork()
    }
}

private fun makeNetwork() {
    val f = br.readLine().toInt()
    val network = mutableMapOf<Int, Int>()
    val friendIndex = mutableMapOf<String, Int>()
    val count = mutableMapOf<Int, Int>()

    var index = -1
    repeat(f) {
        val (a, b) = br.readLine().split(" ")
        val aIndex: Int = friendIndex.getOrPut(a) {
            index++
            network[index] = index
            count[index] = 1
            index
        }
        val bIndex: Int = friendIndex.getOrPut(b) {
            index++
            network[index] = index
            count[index] = 1
            index
        }

        var aHead = network[aIndex]!!
        while (aHead != network[aHead]) {
            aHead = network[aHead]!!
        }
        var bHead = network[bIndex]!!
        while (bHead != network[bHead]) {
            bHead = network[bHead]!!
        }

        if (aHead == bHead) {
            println(count[aHead])
        } else if (aHead < bHead) {
            network[bHead] = aHead
            count[aHead] = count[aHead]!! + count[bHead]!!
            println(count[aHead])
        } else {
            network[aHead] = bHead
            count[bHead] = count[aHead]!! + count[bHead]!!
            println(count[bHead])
        }
    }
}

Comment on lines +30 to +31
parent = defaultdict(str)
count = defaultdict(lambda : 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultdictλ₯Ό 처음 보게 λ˜μ„œ 어떀건지 μ°Ύμ•„λ΄€λŠ”λ°
λ”•μ…”λ„ˆλ¦¬ 인수λ₯Ό μ΄ˆκΈ°ν™”ν•˜μ—¬ μ‚¬μš©ν•˜λŠ”λ° μ‚¬μš© λ˜λ”κ΅°μš”!!!
맀번 κ·Έλƒ₯ μ΄ˆκΈ°ν™”ν• λ•Œ μ–΅μ§€λ‘œ 값을 λ„£μ–΄μ€˜μ„œ μ‚¬μš©ν–ˆλŠ”λ° μ‚¬μš©ν•˜λ©΄ νŽΈν•  것 κ°™λ„€μš”!!
지식이 λŠ˜μ–΄λ‚¬μŠ΅λ‹ˆλ‹€!!!!! κ°μ‚¬ν•©λ‹ˆλ‹€!!

text = "Life is too short, You need python."

d = dict()
for c in text:
    if c not in d:
        d[c] = 1
    else : 
        d[c] += 1

print(d)
from collections import defaultdict

text = "Life is too short, You need python."

d = defaultdict(int)

for c in text:
    d[c] += 1

print(dict(d))
{'L': 1, 'i': 2, 'f': 1, 'e': 3, ' ': 6, 's': 2, 't': 3, 'o': 5, 'h': 2, 'r': 1, ',': 1, 'Y': 1, 'u': 1, 'n': 2, 'd': 1, 'p': 1, 'y': 1, '.': 1}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alstjr7437 🫑🫑🫑

κ·Έκ±° μ—„μ²­ μ—„μ²­ μœ μš©ν•œ κ±°λ‹ˆκΉŒ 체화 ν•˜λ„λ‘ν•˜μ‹œμ§€μš” ~~πŸ‘πŸ‘πŸ‘

@tgyuuAn tgyuuAn merged commit 8da6d44 into main May 22, 2024
@tgyuuAn tgyuuAn deleted the 55-tgyuuAn branch May 22, 2024 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tgyuuAn ν•œ μ€„λ‘œλŠ” μ†Œκ°œν•  수 μ—†λŠ” λ‚¨μž. 리뷰 μ™„λ£Œ βœ”οΈ
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants