본문 바로가기
알고리즘 문제풀이/백준

[백준 1753] 최단경로

by m2162003 2020. 12. 30.

www.acmicpc.net/problem/1753

 

1753번: 최단경로

첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1≤V≤20,000, 1≤E≤300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1≤K≤V)가 주어진다.

www.acmicpc.net

다익스트라 알고리즘을 힙을 사용해서 구현하는 문제이다.

eazymean.tistory.com/290

 

[알고리즘] Dijkstra 다익스트라 알고리즘

- 한 정점에서 여러 개의 다른 정점까지의 최단 거리를 구하는 알고리즘 (single source shortest path) - 간선에 양의 가중치가 존재한다. (음의 가중치까지 있는 건 벨만포드 알고리즘) - 구현시 배열 혹

eazymean.tistory.com

다익스트라 알고리즘 쉬운줄 알았는데^^;; 생각보다 어려웠다.

 

배열을 사용해도 되지만 시간 복잡도가 n^2이 되므로 힙을 사용하자.

#include <stdio.h>
#include <vector>
#include <queue>
#define INF 5000000

using namespace std;
int v, e, k;

struct s
{
  int v, w;
};

struct cmp
{
  bool operator()(const s &t1, const s &t2)
  {
    if (t1.w == t2.w)
    {
      return t1.v > t2.v;
    }
    return t1.w > t2.w;
  }
};
vector<s> arr[20001];
int dis[20001];

priority_queue<s, vector<s>, cmp> pq;
int main(void)
{
  scanf("%d%d%d", &v, &e, &k);

  for (int i = 0; i < e; i++)
  {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    arr[u].push_back({v, w});
  }

  for (int i = 1; i <= v; i++)
  {
    dis[i] = INF;
  }

  dis[k] = 0;
  pq.push({k, 0});

  while (!pq.empty())
  {
    s cur = pq.top();
    pq.pop();

    int cv = cur.v;
    int cw = cur.w;
    if (dis[cv] < cw) // 이미 최솟값
      continue;

    for (int i = 0; i < arr[cv].size(); i++)
    {
      int nw = cw + arr[cv][i].w;
      int nv = arr[cv][i].v;

      if (nw < dis[nv])
      {
        dis[nv] = nw;

        pq.push({nv, nw});
      }
    }
  }

  for (int i = 1; i <= v; i++)
  {
    if (dis[i] == INF)
    {
      printf("INF\n");
    }
    else
    {
      printf("%d\n", dis[i]);
    }
  }

  return 0;
}

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 16112] 5차 전직  (0) 2020.12.31
[백준 11501] 주식  (0) 2020.12.31
[백준 2448] 별 찍기 - 11  (0) 2020.12.29
[백준 5567] 결혼식  (0) 2020.12.29
[백준 11399] ATM  (0) 2020.12.29

댓글