Dijkstra
36051 ワード
ダエストラ
DPの最短パスナビゲーションアルゴリズムを利用する.
幹線料金に負が含まれていない場合にのみ使用できます.
探索の原理.
選択したノードから他のノードへのすべてのパスを参照しながら、最短コストで更新します.
(aからbへの最短パスを取得するには、最終的にはすべてのノードにアクセスして最短パスを更新する必要があります)
コメントサイト
JAVA
class Graph{
private int n; //노드들의 수
private int maps[][]; //노드들간의 간선 비용 1->3 비용 : 3 이라면 maps[1][3] = 3
public Graph(int n){
this.n = n;
maps = new int[n+1][n+1];
}
//양방향일 경우
public void input(int i,int j,int w){
maps[i][j] = w;
maps[j][i] = w;
}
public void dijkstra(int v){
int distance[] = new int[n+1]; //최단 거리를 저장할 변수
boolean[] check = new boolean[n+1]; //해당 노드를 방문했는지 체크할 변수
//distance값 초기화.
for(int i=1;i<n+1;i++){
distance[i] = Integer.MAX_VALUE;
}
//시작노드값 초기화.
distance[v] =0;
check[v] =true;
//연결노드 distance갱신
for(int i=1;i<n+1;i++){
if(!check[i] && maps[v][i] !=0){
distance[i] = maps[v][i];
}
}
for(int a=0;a<n-1;a++){
//원래는 모든 노드가 true될때까지 인데
//노드가 n개 있을 때 다익스트라를 위해서 반복수는 n-1번이면 된다.
//원하지 않으면 각각의 노드가 모두 true인지 확인하는 식으로 구현해도 된다.
int min=Integer.MAX_VALUE;
int min_index=-1;
//최소값 찾기
for(int i=1;i<n+1;i++){
if(!check[i] && distance[i]!=Integer.MAX_VALUE){
if(distance[i]<min ){
min=distance[i];
min_index = i;
}
}
}
check[min_index] = true;
for(int i=1;i<n+1;i++){
if(!check[i] && maps[min_index][i]!=0){
if(distance[i]>distance[min_index]+maps[min_index][i]){
distance[i] = distance[min_index]+maps[min_index][i];
}
}
}
}
//결과값 출력
for(int i=1;i<n+1;i++){
System.out.print(distance[i]+" ");
}
System.out.println("");
}
}
// 현재 노드에서 최단 거리의 노드로 먼저 방문하고, 최단 경로 비용을 줄임.
//이후 다시 최단 거리 노드 이동하여 비용 줄임. 모두 방문 할때 까지 반복
//이해하긴 쉬우나 시간복잡도가 김
優先キュー import java.io.*;
import java.util.*;
//
class Node implements Comparable<Node>{
int end, weight;
public Node(int end, int weight){
this.end = end;
this.weight = weight;
}
@Override
public int compareTo(Node o) {
return weight - o.weight;
}
}
public class Main {
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
private static final int INF = 100_000_000;
static int v,e,k;
static List<Node>[] list;
static int[] dist;
public static void main(String[] args) throws IOException {
StringTokenizer st = new StringTokenizer(br.readLine());
v = Integer.parseInt(st.nextToken());
e = Integer.parseInt(st.nextToken());
k = Integer.parseInt(br.readLine());
list = new ArrayList[v + 1];
dist = new int[v + 1];
Arrays.fill(dist, INF);
for(int i = 1; i <= v; i++){
list[i] = new ArrayList<>();
}
// 리스트에 그래프 정보를 초기화
for(int i = 0 ; i < e; i++){
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
int weight = Integer.parseInt(st.nextToken());
// start에서 end로 가는 weight 가중치
list[start].add(new Node(end, weight));
}
StringBuilder sb = new StringBuilder();
// 다익스트라 알고리즘
dijkstra(k);
// 출력 부분
for(int i = 1; i <= v; i++){
if(dist[i] == INF) sb.append("INF\n");
else sb.append(dist[i] + "\n");
}
bw.write(sb.toString());
bw.close();
br.close();
}
private static void dijkstra(int start){
PriorityQueue<Node> queue = new PriorityQueue<>();
boolean[] check = new boolean[v + 1];
queue.add(new Node(start, 0));
dist[start] = 0;
while(!queue.isEmpty()){
Node curNode = queue.poll();
int cur = curNode.end;
if(check[cur] == true) continue;
check[cur] = true;
for(Node node : list[cur]){
if(dist[node.end] > dist[cur] + node.weight){
dist[node.end] = dist[cur] + node.weight;
queue.add(new Node(node.end, dist[node.end]));
}
}
}
}
}
Reference
この問題について(Dijkstra), 我々は、より多くの情報をここで見つけました https://velog.io/@away0419/다익스트라-Dijkstraテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol