2020-1ν•™κΈ°, λŒ€ν•™μ—μ„œ β€˜μ•Œκ³ λ¦¬μ¦˜β€™ μˆ˜μ—…μ„ λ“£κ³  κ³΅λΆ€ν•œ λ°”λ₯Ό μ •λ¦¬ν•œ κΈ€μž…λ‹ˆλ‹€. 지적은 μ–Έμ œλ‚˜ ν™˜μ˜μž…λ‹ˆλ‹€ :) 전체 ν¬μŠ€νŠΈλŠ” Algorithm ν¬μŠ€νŠΈμ—μ„œ ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.

4 minute read

2020-1ν•™κΈ°, λŒ€ν•™μ—μ„œ β€˜μ•Œκ³ λ¦¬μ¦˜β€™ μˆ˜μ—…μ„ λ“£κ³  κ³΅λΆ€ν•œ λ°”λ₯Ό μ •λ¦¬ν•œ κΈ€μž…λ‹ˆλ‹€. 지적은 μ–Έμ œλ‚˜ ν™˜μ˜μž…λ‹ˆλ‹€ :) 전체 ν¬μŠ€νŠΈλŠ” Algorithm ν¬μŠ€νŠΈμ—μ„œ ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.


μš°λ¦¬κ°€ μ§€κΈˆκΉŒμ§€ μ‚΄νŽ΄λ³Έ β€œShortest Path” λ¬Έμ œλŠ” λͺ¨λ‘ 좜발 λ…Έλ“œ $s$와 도착 λ…Έλ“œ $t$κ°€ κ³ μ •λœ κ²½μš°μ˜€λ‹€. κ·ΈλŸ¬λ‚˜ λ•Œλ‘œλŠ” μ£Όμ–΄μ§€λŠ” λ…Έλ“œ 쿼리 $(s, t)$에 λŒ€ν•œ shortest pathλ₯Ό μ°Ύκ±°λ‚˜ λ˜λŠ” κ·Έλž˜ν”„μ— μ‘΄μž¬ν•˜λŠ” λͺ¨λ“  λ…Έλ“œ 쌍 $(u, v)$ μ‚¬μ΄μ˜ shortest pathλ₯Ό μ°Ύκ³  싢을 수 μžˆλ‹€.

λ§Œμ•½ 이것을 <Dijkstra Algorithm>을 μ‚¬μš©ν•΄ $V$개의 λ…Έλ“œμ— λŒ€ν•΄μ„œ β€œsingle-source shortest path”λ₯Ό 찾고자 ν•œλ‹€λ©΄, 총 $V \times O(VE) = O(V^2 E)$의 μ‹œκ°„μ΄ κ±Έλ¦°λ‹€.

κ·Έ.러.λ‚˜. <DP>λ₯Ό μ‚¬μš©ν•˜λ©΄, 쒀더 λΉ λ₯Έ μ‹œκ°„ μ•ˆμ— 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€!! 😁 이 μ•Œκ³ λ¦¬μ¦˜μ„ <Floyd-Warshall Aglrorithm>라고 ν•œλ‹€.


μš°λ¦¬λŠ” 두 정점 $(i, j)$을 μž‡λŠ” μ΅œλ‹¨ 경둜λ₯Ό μ•„λž˜μ™€ 같이 κ²½μœ μ§€ $k$λ₯Ό κ±°μΉ˜λŠ” 문제둜 생각해볼 수 μžˆλ‹€!!

즉, 두 정점을 μž‡λŠ” μ΅œλ‹¨ 경둜λ₯Ό $k-1$κΉŒμ§€μ˜ λ…Έλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°μ™€ $k$κΉŒμ§€ λ…Έλ“œλ₯Ό 포함해 μ‚¬μš©ν•œ 경우(pass through $k$)둜 λ‚˜λˆ„μ–΄ λ‘˜ 쀑 μ΅œλ‹¨ 경둜λ₯Ό μ„ νƒν•œλ‹€.

μ΄λ•Œ, μ£Όμ˜ν•  점은 μ΄λ ‡κ²Œ κ²½μœ μ§€λ₯Ό κ±°μ³κ°€λŠ” 방법을 μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„  κ²½μœ ν•˜λŠ” 경둜λ₯Ό μ΄λ£¨λŠ” sub-path μ—­μ‹œ μ΅œλ‹¨ κ²½λ‘œμž„μ΄ 보μž₯λ˜μ–΄μ•Ό ν•œλ‹€!

이λ₯Ό μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ ν‘œν˜„ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€.

// initialize
for all $(i, j) \in E$
  $\text{dist}(i, j, 0) = \ell(i, j)$

for $k=1$ to $n$:
  for $i=1$ to $n$:
    for $j=1$ to $n$:
      $\text{dist}(i, j, k) = \min \{ \text{dist}(i, j, k-1), \; \text{dist}(i, k, k-1) + \text{dist}(k, j, k-1)\}$

사싀 μ‹€μ œλ‘œ κ΅¬ν˜„μ„ 해보면, 3차원 배열이 μ•„λ‹ˆλΌ $k$λ₯Ό μ—†μ•€ 2차원 λ°°μ—΄λ‘œλ„ μΆ©λΆ„νžˆ 잘 λ™μž‘ν•œλ‹€ πŸ˜‰

μ‹œκ°„ λ³΅μž‘λ„λŠ” κΈ°μ‘΄ DFS 기반의 $O(V^2 E)$μ—μ„œ $O(V^3)$둜 μ€„μ–΄λ“€μ—ˆλ‹€!! (일반적으둜 sparse graphκ°€ μ•„λ‹ˆλΌλ©΄ $V < E$이닀.)


κ΅¬ν˜„

  • adjacency matrix둜 연결성을 ν‘œν˜„ν•˜λŠ” κ±Έ μΆ”μ²œ
  • adjacency matrix μ΄ˆκΈ°ν™” μžŠμ§€ 말것; fill();
    • μ΄ˆκΈ°ν™” ν•  λ•Œ, INT_MAX와 같이 맀우 큰수둜 ν•˜κ²Œ 되면 overflow λ•Œλ¬Έμ— 잘λͺ»λœ κ²°κ³Όλ₯Ό λ±‰μŒ;;
  • κ΅¬ν˜„ μžμ²΄λŠ” 정말 간단함! LIS, edit distance κΈ‰μœΌλ‘œ μ‰¬μš΄ κ΅¬ν˜„!
// initialization 1
fill(&dist[0][0], &dist[N+1][N+1], MAX2);

// initialization 2
for (int i = 0; i < M; i++) {
  int a, b;
  scanf("%d %d", &a, &b);

  dist[a][b] = 1;
  dist[b][a] = 1;
}

// Floyd-Warshall
for (int k = 1; k <= N; ++k) {
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= N; ++j) {
      if(dist[i][k] == MAX2 || dist[k][j] == MAX2) continue;

      dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
    }
  }
}

참고둜 <Flyod-Warshall>은 λ…Έλ“œμ˜ μˆ˜κ°€ 10,000κ°€ 되면 λ„ˆλ¬΄ λ§Žμ€ λ©”λͺ¨λ¦¬λ₯Ό μ“°κΈ° λ•Œλ¬Έμ— μ“Έ 수 μ—†λ‹€! λ°±μ€€ 1325번: 효율적인 해킹이 λ©”λͺ¨λ¦¬ λ•Œλ¬Έμ— <Flyod-Warshall>을 μ“Έ 수 μ—†λŠ” μ˜ˆμ΄λ‹€!

μΆ”μ²œ 문제

Categories:

Updated: