Open WonYong-Jang opened 6 years ago
public class Main {
static int N, M;
static int INF = 987654321;
static ArrayList<ArrayList<Node>> adj = new ArrayList<>();
static int[] dis = new int[505];
static int[] inQ = new int[505];
static int[] cycle = new int[505];
static Queue<Integer> que = new LinkedList<>();
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
for(int i=0; i<= N; i++) {
adj.add(new ArrayList<>());
dis[i] = INF;
}
int dx =0, dy =0, cost = 0;
for(int i=1; i<= M; i++) {
st = new StringTokenizer(br.readLine());
dx = Integer.parseInt(st.nextToken());
dy = Integer.parseInt(st.nextToken());
cost = Integer.parseInt(st.nextToken());
adj.get(dx).add(new Node(dy, cost));
}
que.add(1);
dis[1] = 0; //최단 거리 배열
inQ[1] = 1; // 큐에 들어있는지 확인 배열
cycle[1]++;
while(!que.isEmpty())
{
int cur = que.poll();
inQ[cur] = 0;
for(Node next : adj.get(cur))
{
if(dis[next.dx] > next.cost + dis[cur])
{
dis[next.dx] = next.cost + dis[cur];
if(inQ[next.dx] == 0)
{
cycle[next.dx]++;
if(cycle[next.dx] >= N) {
System.out.println(-1);
return;
}
inQ[next.dx] = 1;
que.add(next.dx);
}
}
}
}
for(int i=2; i<= N; i++)
{
if(dis[i] == INF) System.out.println(-1);
else System.out.println(dis[i]);
}
}
static class Node {
int dx, cost;
Node(int a, int b) {
dx=a; cost=b;
}
}
}
ex ) 1, 1, 1, 1, 2, 2, 2 큐를 앞에서 부터 하나씩 빼고 계산한 결과가 1이 나오면 다시 앞으로 넣고 하나 플러스되서 2가 나오게 되면 뒤로 넣고 정렬을 유지
https://koitp.org/problem/BOI_2011_BULB/read/
- dist를 우선순위 큐 ( 내림차순) 배열로 만들어두고 next의 최단 거리 갯수가 k 보다 작다면 계속 추가해주고 k 와 같다면 가장 큰것들과 비교해서 더작은 값으로 갱신해주게 된다면 dist[i] 배열의 peek() 값은 k번째 경로가 들어 있게 된다.
따라서 dist[i].size() 가 k개가 들어있다면 해당경로로 가는 k 번째 최단경로가 존재!! 그렇지 않다면 k번째로 가는 최단경로가 존재하지 않는다!!
while(!que.isEmpty())
{
Node n = que.poll();
if(n.cost > dist[n.dx].peek()) continue; // 시간 컷트 !
for(Node next : adj[n.dx])
{
long nextCost = next.cost + n.cost;
if(dist[next.dx].size() < K) // k 개 가 될때까지 삽입
{
dist[next.dx].add(nextCost);
que.add(new Node(next.dx, nextCost));
}
else // 크기가 k 개가 되었다면 가장 큰 top 과 비교하여 갱신
{
if(dist[next.dx].peek() > nextCost)
{
dist[next.dx].poll();
dist[next.dx].add(nextCost);
que.add(new Node(next.dx, nextCost));
}
}
}
class Solution {
public final int INF = 1<<30;
public int[][] dist;
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
dist = new int[K+2][n];
for(int[] d : dist)
{
Arrays.fill(d, INF);
}
dist[0][src] = 0;
for(int i=0; i<= K; i++)
{
dist[i][src] = 0;
for(int[] cur : flights)
{
if(dist[i][cur[0]] != INF && dist[i+1][cur[1]] > cur[2] + dist[i][cur[0]])
{
dist[i+1][cur[1]] = cur[2] + dist[i][cur[0]];
}
}
}
return dist[K+1][dst] == INF ? -1 : dist[K+1][dst] ;
}
public int min(int a, int b) { return a > b ? b: a;}
}
다익스트라 알고리즘은
그래프의 어떤 정점 하나를 시작점으로 선택하고, 나머지 정점들로의 최단거리를 모두 구함 시작점 자신은 0 정점 개수가 V, 간선 개수가 E일 때 기본적인 최적화를 거치면 O(ElogV)의 시간복잡도
// 인접 리스트 정점 갯수만큼 할당 해주고 인접리스트 연결 할 것 // dis 배열 모두 INF 로 초기화 해주고 시작점 0으로 놓고 시작 ! public static void solve() { PriorityQueue que = new PriorityQueue<>(new Mysort());
que.add(new Node(S,0)); // 시작점
dis[S] = 0;
}
/**
*/ public class Main {
static int N, M; static int[][] data = new int[6001][3]; // input 간선 표 static int[] d = new int[501]; // cost 정보 배열 static final int INF = 6005*10000; public static void main(String[] args) throws IOException { int dx,dy,cost; for(int i=1; i<= M; i++) { data[i][0] = dx; data[i][1] = dy; data[i][2] = cost; }
} }