레이블이 다익스트라인 게시물을 표시합니다. 모든 게시물 표시
레이블이 다익스트라인 게시물을 표시합니다. 모든 게시물 표시

2016년 5월 27일 금요일

알고스팟 - ROUTING

https://algospot.com/judge/problem/read/ROUTING

노이즈의 증폭이 최소가 되는 경로를 찾는 문제이다. 책에는 "노이즈 $c$ 는 언제나 1 이상 3 이하의 실수입니다" 라고 나와있다고 한다.

음.. 이게 딱히 문제는 없을 거 같지만, $c$의 범위를 몰라서 정답의 범위를 모르기때문에, 무한대값(INF)를 설정을 못한다. INF=987654321 로 설정하면 오답이 나온다.
987654321 보다 큰 경로만 남아있을 때, 방문하지 않은 정점들은 987654321 일테니 탐색하지 않아버린다.

근데 모든 노이즈가 3이면 어떻게 될까. 3^10000 ...!!

방문한 노드와 방문하지 않은 노드를 따로 구분해야한다. 다익스트라에서는 음수인 가중치가 없을테니 방문하지 않은 노드를 -1 로 해도 될거같다.

2016년 4월 5일 화요일

1445 - 일요일 아침의 데이트

https://www.acmicpc.net/problem/1445

다익스트라에서 선택해야할 우선순위 조건이 다음과 같이 2가지이다.
  1. 지나가는 쓰레기의 수는 최소로
  2. 쓰레기 근처를 지나는 칸의 수를 최소로
S에서 F까지 가면서 위 2가지의 가중치가 최소가 되게 선택하면서 진행하면 된다.

10217 - KCM Travel

https://www.acmicpc.net/problem/10217

주어진 비용으로 갈 수 있는 1번~모든 노드의 최단 거리를 구한다.

구하는 과정에서 아래와 같이 정보를 저장한다.
dp(i, k) = i번 노드까지 k의 비용으로 갔을 때의 최소 시간
주어진 비용 내에서 N번 노드까지 간 최소 시간을 구하면 된다.

1261 - 알고스팟

https://www.acmicpc.net/problem/1261

2차원 평면에서 큐를 넣고 빼고 하는 코드를 적으면 왠지 귀찮을꺼같아서 각 칸을 노드처럼 썼다. 예를 들면, 각 칸의 노드 번호는 아래와 같다.
// 4x2 크기의 평면
0123
4567
1인 칸으로 가는 경우에는 벽을 부숴야하므로 가중치가 1인 간선이 있다고 생각하면 된다. (그 외에는 가중치가 0인 간선)

그럼 다익스트라로 0번 -> h*w-1번 으로 가는 최단 경로 문제가 된다.
같이 보기
 - 알고스팟: BOJ

2611 - 자동차 경주

다익스트라에서 큐의 우선순위를 "가중치가 높은 노드"로 바꾸면 된다.

중간에 시작 노드를 지나갈 수 없으므로 (처음을 제외한) 시작 노드 이후의 경로는 탐색하지 않도록 한다.

경로 출력은 큐에 넣는 작업을 할때마다 그 때의 이전 노드를 따로 저장 (즉, 어디서부터 왔는 가를 저장)하여 마지막엔 시작 노드로부터 그 역순으로 따라올라가면 경로를 얻을 수 있다.

2016년 3월 2일 수요일

1238 - 파티

처음에는 플로이드 와샬로 접근해봤다. 아니나다를까 N=1,000 이라서 $O(N^3)$ 은 시간초과였다.

처음으로 다익스트라를 구현해봤다.
잘 동작하는지는 모르겠고 흉내만 내는 것 같다.
#define INF 987654321

typedef pair<int,int> ii;

int dijkstra(vector<ii> adj[], int n, int s, int e){
    vector<int> cost(n, INF); /* s 로부터 i까지의 최소 비용 */
    priority_queue<ii /*(-weight, next)*/> q;
    q.push({0, s});
    cost[s] = 0;
    while(!q.empty()){
        int pos = q.top().second;
        int dist = -q.top().first;
        q.pop();
        
        for(int i=0; i<adj[pos].size(); ++i){
            ii& next = adj[pos][i]; /* (next, weight) */
            if(dist + next.second >= cost[next.first]) continue;
            q.push({-(dist+next.second), next.first});
            cost[next.first] = dist+next.second;
        }
    }
    return cost[e];
}
예제가 잘 나오길래 제출해봤는데 정답이 잘 나왔다. 시간이 좀 걸리는걸 보니 N이 좀 커지면 시간초과가 나올 듯 하다.

게시글 목록