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

48-tgyuuAn #171

Merged
merged 2 commits into from
May 3, 2024
Merged

48-tgyuuAn #171

merged 2 commits into from
May 3, 2024

Conversation

tgyuuAn
Copy link
Member

@tgyuuAn tgyuuAn commented Mar 26, 2024

πŸ”— 문제 링크

골λͺ©κΈΈ

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

1μ‹œκ°„ 20λΆ„

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

  • ν•˜λ‚˜μ˜ μΆœλ°œμ§€μ—μ„œ μ—¬λŸ¬ 개의 λͺ©μ μ§€κΉŒμ§€ κ±Έλ¦¬λŠ” 데 μ΅œμ†Œ λΉ„μš©μ„ κ΅¬ν•˜λŠ” 경우 : λ‹€μ΅μŠ€νŠΈλΌ
  • μ—¬λŸ¬ 개의 μΆœλ°œμ§€μ—μ„œ μ—¬λŸ¬ 개의 λͺ©μ μ§€λ‘œ κ±Έλ¦¬λŠ” 데 μ΅œμ†Œ λΉ„μš©μ„ κ΅¬ν•˜λŠ” 경우 : ν”Œλ‘œμ΄λ“œ μ›Œμ…œ
  • 음수 κ°€μ€‘μΉ˜κ°€ μžˆλŠ” 경우, 음수 κ°€μ€‘μΉ˜λ‘œ 인해 음수 사이클이 λ°œμƒν•  것 같은 경우 : 벨만 ν¬λ“œ







이 λ¬Έμ œλŠ” μ•„λž˜μ™€ 같이 음수 κ°€μ€‘μΉ˜κ°€ μžˆμœΌλ‹ˆκΉŒ 벨만 ν¬λ“œλ₯Ό μ‚¬μš©ν•¨μ„ μ‰½κ²Œ λ– μ˜¬λ¦΄ 수 μžˆλ‹€.

image

λ²¨λ§Œν¬λ“œμ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” $총 λ…Έλ“œμ˜ 수 * κ°„μ„ μ˜ 갯수$ μ΄λ―€λ‘œ 총 200만으둜 μ‹œκ°„ λ³΅μž‘λ„ μ•ˆμœΌλ‘œλ„ 세이프 κ°€λŠ₯ν•˜λ‹€.







벨만 ν¬λ“œμ˜ μžμ„Έν•œ κ΅¬ν˜„ 방법은 @gjsk132 μ—κ²Œ μœ„μž„..

μ˜€ν›„μ— λ””μŠ€μ½”λ“œ μ•Œκ³ λ¦¬μ¦˜ λ…ΈνŠΈμ— 올라올 것이닀 ν—ˆν—ˆ.

image




++ κΈ€ μ˜¬λΌμ™”μŠ΅λ‹ˆλ‹€. λ””μŠ€μ½”λ“œ 채널에 μ•Œκ³ λ¦¬μ¦˜ λ…ΈνŠΈ μ½μ–΄λ³΄μ„Έμš”!

image







λ‹€μ‹œ 문제둜 λŒμ•„μ™€μ„œ,

그러면 μ΄λ ‡κ²Œ 생각할 수 μžˆλ‹€.

'음수 사이클이 λ°œμƒν•˜λŠ” 경우 "-1" 을 좜λ ₯ν•˜λ©΄ λ˜κ² λ‹€ ...!'

'μ•„, 음수 사이클이 λ°œμƒν•˜μ§€ μ•Šλ”λΌλ„ 간선이 λ§ˆμ§€λ§‰ λ…Έλ“œ κΉŒμ§€ μ—°κ²°λ˜μ§€ μ•Šμ„ κ²½μš°λ„ μžˆμœΌλ‹ˆκΉŒ, λ§ˆμ§€λ§‰ λ…Έλ“œλ‘œ μ—°κ²°λ˜μ§€ μ•Šμ„ κ²½μš°λ„ "-1"을 좜λ ₯ν•΄μ•Όκ² λ‹€.'

μ΄λ ‡κ²Œλ§Œ μ‚¬κ³ ν•˜κ³  μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ‚˜κ°”λ‹€.

import sys

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

N, M = map(int, input().split())
edge = []

# κ°„μ„  정보 λ°›μŒ
for _ in range(M):
    start, destination, cost = map(int,input().split())
    edge.append([start, destination, cost])
    
# 초기 μ„ΈνŒ…
board = [-int(1e9) for _ in range(N+1)]
board[1] = 0

# 졜적의 경둜λ₯Ό μ°ΎκΈ° μœ„ν•΄ 역좔적 ν•˜κΈ° μœ„ν•΄μ„œ 이전 λ…Έλ“œλ₯Ό 기둝
prev_node = [-1 for _ in range(N+1)]

for _ in range(N-1):
    for start, destination, cost in edge:
        if board[destination] < board[start] + cost:
            board[destination] = board[start] + cost
            prev_node[destination] = start

for start, destination, cost in edge:
    # 사이클 λ°œμƒ
    if board[destination] < board[start] + cost:
        print(-1)
        break

# 사이클이 없을 경우
else: 
    answer = []
    now = N
    while now != 1:
        answer.append(now)
        now = prev_node[now]
    answer.append(now)
    
    print(*answer[::-1])

# 총 κ°„μ„  = 2만개,
# 총 λ…Έλ“œ = 100개
# 벨만 ν¬λ“œ = ( κ°„μ„  X λ…Έλ“œ ) -> 200만 μ‹œκ°„ λ³΅μž‘λ„ κ°€λŠ₯.

μœ„ μ½”λ“œλ₯Ό μ œμΆœν•˜κ³ λ‚˜λ‹ˆ,

μ •λ‹΅ νΌμ„ΌνŠΈκ°€ μ­‰μ­‰ μ˜¬λΌκ°€μ„œ 맞좘 쀄 μ•Œκ³  μ’‹μ•„ν–ˆλ‹€.

근데 76νΌμ—μ„œ 계속 κ±Έλ Έλ‹€.

image







흠.. λ„λŒ€μ²΄ μ–΄λ””κ°€ λ¬Έμ œμ˜€λ˜ 걸까..

근데 κ³¨λ“œ 1치고 λ‚œμ΄λ„κ°€ λ„ˆλ¬΄ μ‰¬μš΄ 것 κ°™μ•„μ„œ λ‹€μ‹œ 문제λ₯Ό 꼼꼼히 μ½μ–΄λ³΄μ•˜λ‹€.

μ•„λž˜ λ¬Έμž₯이 λ‚΄ 이λͺ©μ„ λŒμ—ˆλ‹€.

image







흠... λΆ„λͺ… 졜적의 κ²½λ‘œκ°€ μ•„λž˜ 경우 말고도 λ‹€λ₯Έ κ²½μš°κ°€ μžˆκ΅¬λ‚˜ 생각을 ν–ˆλ‹€.

'음수 사이클이 λ°œμƒν•˜λŠ” 경우 "-1" 을 좜λ ₯ν•˜λ©΄ λ˜κ² λ‹€ ...!'

'μ•„, 음수 사이클이 λ°œμƒν•˜μ§€ μ•Šλ”λΌλ„ 간선이 λ§ˆμ§€λ§‰ λ…Έλ“œ κΉŒμ§€ μ—°κ²°λ˜μ§€ μ•Šμ„ κ²½μš°λ„ μžˆμœΌλ‹ˆκΉŒ, λ§ˆμ§€λ§‰ λ…Έλ“œλ‘œ μ—°κ²°λ˜μ§€ μ•Šμ„ κ²½μš°λ„ "-1"을 좜λ ₯ν•΄μ•Όκ² λ‹€.'

근데 λ„μ €νžˆ 아무리 봐도 λ– μ˜€λ₯΄μ§€κ°€ μ•ŠλŠ”λ‹€.

κ·Έλž˜μ„œ 질문 κ²Œμ‹œνŒμ—μ„œ λ°˜λ‘€λ₯Ό λ’€μ‘Œλ‹€.







image

μ•„λΏ”μ‹Έ....

"사이클이 μžˆλ”λΌλ„, ν•΄λ‹Ή 사이클이 μ‹œμž‘ 지점 - λͺ©ν‘œ 지점 κ³Ό 연관이 μ—†λŠ” 경우 졜적의 경둜λ₯Ό 찾을 수 μžˆλ‹€."

즉, μœ„μ˜ λ°˜λ‘€λ₯Ό 보면 2번과 3번 λ…Έλ“œλŠ” 사이클을 λ§Œλ“€μ–΄ λ¬΄ν•œ 루프λ₯Ό 돌기 λ•Œλ¬Έμ— μœ„ μ˜ˆμ‹œμ—μ„œλŠ” 사이클이 μ‘΄μž¬ν•œλ‹€κ³  ν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ, μ‹œμž‘ 지점인 1번과 λͺ©ν‘œ 지점인 4번 λ…Έλ“œλŠ” 사이클에 ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ―€λ‘œ, 졜적의 경둜λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.







그러면 벨만 ν¬λ“œλ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ, 음수 사이클이 λ°œμƒν•¨μ„ νŒŒμ•…ν•œ μˆœκ°„ ν•΄λ‹Ή λ…Έλ“œλ₯Ό κΈ°μ€€μœΌλ‘œ BFS ν˜Ήμ€ DFSλ₯Ό λŒλ €μ„œ μ—°κ΄€λ˜μ–΄ μžˆλŠ” λ…Έλ“œλ₯Ό νŒŒμ•…ν•œλ‹€.

이 κ³Όμ •μ—μ„œ μ‹œμž‘ 지점인 1번 λ…Έλ“œμ™€ λͺ©ν‘œ 지점인 N번 λ…Έλ“œκ°€ ν¬ν•¨λ˜μ–΄ 있으면 λ°”λ‘œ -1을 좜λ ₯ν•˜κ³ ,

ν•΄λ‹Ή λ…ΈλŠλ“€μ΄ ν¬ν•¨λ˜μ§€ μ•Šμ•˜μ„ 경우 사이클이 없을 λ•Œμ™€ 같이 μ‹œμž‘ 지점뢀터 λ§ˆμ§€λ§‰ μ§€μ κΉŒμ§€ 연결될 수 μžˆλŠ” 지 μ²΄ν¬ν•œλ‹€.







끝 지점 κΉŒμ§€ 이어진닀면 ν•΄λ‹Ή 경둜λ₯Ό 좜λ ₯, 아닐 경우 -1을 좜λ ₯.

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

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

gjsk132 commented Mar 27, 2024

벨만 ν¬λ“œμ˜ μžμ„Έν•œ κ΅¬ν˜„ 방법은 @gjsk132 μ—κ²Œ μœ„μž„..

μ˜€ν›„μ— λ””μŠ€μ½”λ“œ μ•Œκ³ λ¦¬μ¦˜ λ…ΈνŠΈμ— 올라올 것이닀 ν—ˆν—ˆ.

어라라

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.

λ‹€μ΅μŠ€νŠΈλΌλŠ” κ°œλ…λ§Œ μ•Œκ³  μžˆμ—ˆκ³ , 'ν”Œλ‘œμ΄λ“œ μ›Œμ…œ', 'λ²¨λ§Œν¬λ“œ'λŠ” 처음 λ“€μ–΄λ΄€λ„€μš” γ„·γ„·
λ‚˜μ˜λ‹˜κ³Ό νƒœκ·œλ‹˜ 덕뢄에 μ•Œκ³ λ¦¬μ¦˜ ν•˜λ‚˜ 또 쀍쀍 ν•΄κ°‘λ‹ˆλ‹€ !!

λ‹€μ΅μŠ€νŠΈλΌμ—μ„œ 음의 κ°€μ€‘μΉ˜ λ•Œλ¬Έμ— λ¬΄ν•œλ£¨ν”„λ₯Ό 돌게 λ˜λŠ” λ¬Έμ œκ°€ λ°œμƒν•΄μ„œ 벨만 ν¬λ“œλ₯Ό μ‚¬μš©ν•˜κ³ , μ–‘μ˜ κ°€μ€‘μΉ˜λ§Œ μžˆλŠ” κ²½μš°μ—λŠ” λ‹€μ΅μŠ€νŠΈλΌλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 더 νš¨μšΈμ μ΄λ‹€!

아직 이 문제λ₯Ό ν’€κΈ°μ—” λ‹€μ΅μŠ€νŠΈλΌλ„ μ œλŒ€λ‘œ λͺ¨λ₯΄λŠ” 것 κ°™μ•„μ„œ μ €μž₯ν•΄λ‘μ—ˆλ‹€κ°€ λ‹€μ΅μŠ€νŠΈλΌ κ³΅λΆ€ν•˜κ³  λ‹€μ‹œ ν’€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹· !! πŸ”₯πŸ”₯

μ†Œλ§ˆ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€ λŒ€μž₯λ‹˜ πŸ˜ŽπŸŽ‰

# 사이클이 λ°œμƒν•΄λ„ κ²½λ‘œλž‘ 관련이 없을 μˆ˜λ„ μžˆμœΌλ―€λ‘œ,
# 사이클이 λ°œμƒν•œ 지점이 λͺ©ν‘œ 지점과 관련이 μžˆλŠ”μ§€ 체크크
deq = deque([start])
visited = {start,}
Copy link
Collaborator

@H0ngJu H0ngJu Mar 29, 2024

Choose a reason for hiding this comment

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

μ‚¬μ†Œν•œκ±°κΈ΄ ν•œλ°, start 뒀에 ,<< 이건 별 의미 μ—†λŠ” κ±΄κ°€μš”? πŸ€”

Copy link
Member Author

Choose a reason for hiding this comment

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

집합을 μ„ μ–Έν•  λ•Œμ—λŠ” 항이 ν•˜λ‚˜ 밖에 없을 λ•Œ 콀마λ₯Ό λ„£μ–΄μ€˜μ•Ό ν•΄μš”!

μœ„ μ½”λ“œλŠ”

visited = set()
visited.add(start)

λž‘ λ™μΌν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€!

Copy link
Collaborator

@pknujsp pknujsp left a comment

Choose a reason for hiding this comment

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

λ“œλ””μ–΄ ν’€μ—ˆμŠ΅λ‹ˆλ‹€
5μ‹œκ°„ μ—°μ†μœΌλ‘œ μž‘μ€ λ¬Έμ œλŠ” 이게 처음인거 κ°™λ„€μš”

INF = -int(1e9)

N, M = map(int, input().split())
edges = [[] for _ in range(N + 1)]

for _ in range(M):
    u, v, w = map(int, input().split())
    edges[u].append((v, w))

dist = [INF] * (N + 1)
dist[1] = 0
path = list(range(N + 1))

for _ in range(N - 1):
    for u in range(1, N + 1):
        for v, w in edges[u]:
            if dist[u] != INF and dist[v] < dist[u] + w:
                dist[v] = dist[u] + w
                path[v] = u

connected_start_to_end = False
queue = deque()
visited = set()

for u in range(1, N + 1):
    for v, w in edges[u]:
        if dist[u] != INF and dist[v] < dist[u] + w:
            queue.append(v)
            visited.add(v)

while queue:
    current = queue.popleft()
    
    if current == 1 or current == N:
        connected_start_to_end = True
        break

    for v, w in edges[current]:
        if v not in visited:
            visited.add(v)
            queue.append(v)

if connected_start_to_end:
    print(-1)
    exit()

if dist[N] == INF:
    print(-1)
    exit()

q = deque()
x = N

while x != path[x]:
    q.appendleft(x)
    x = path[x]
    
q.appendleft(x)
print(*q)

밑에 μ½”λ“œκ°€ 76%μ—μ„œ λ§‰ν˜”λ˜ μ½”λ“œμ˜ˆμš”

μ•„κΉŒ μ „ μ—λŠ” 사이클이 μžˆλ”λΌλ„, ν•΄λ‹Ή 사이클이 μ‹œμž‘ 지점 - λͺ©ν‘œ 지점 κ³Ό 연관이 μ—†λŠ” 경우 졜적의 경둜λ₯Ό 찾을 수 μžˆλ‹€.
νƒœκ·œλ‹˜ λ‚΄μš© λ³΄κΈ°μ „μ—λŠ” 이 λ‚΄μš©μ„ μ•„μ˜ˆ μƒκ°ν•˜μ§€λ„ λͺ»ν–ˆμ—ˆκ³ , 뒀에 이거 μ²˜λ¦¬ν•˜λŠ”λ° ν•œ 3μ‹œκ°„ κ±Έλ ΈμŠ΅λ‹ˆλ‹€

edges = [list(map(int, input().split())) for _ in range(M)]

dist = [INF] * (N + 1)
dist[1] = 0
path = list(range(N + 1))

for n in range(N):
    updated = False
    for u, v, w in edges:
        if dist[u] != INF and dist[v] < dist[u] + w:
            if n == N - 1:
                print(-1)
                exit()
                
            dist[v] = dist[u] + w
            path[v] = u
            updated = True
                
    if not updated:
        break

if dist[N] == INF:
    print(-1)
    exit()

q = deque([N])
x = path[N]

while x != path[x]:
    q.appendleft(x)
    x = path[x]

q.appendleft(1)
print(*q)

@tgyuuAn tgyuuAn merged commit 3c10fb8 into main May 3, 2024
@tgyuuAn tgyuuAn deleted the 48-tgyuuAn branch May 3, 2024 15:34
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.

4 participants