관리 메뉴

Partially Committed

[λ°±μ€€ 11657] νƒ€μž„λ¨Έμ‹  (JAVA) λ³Έλ¬Έ

πŸ”₯ Algorithm || λ¬Έμ œν’€μ΄/PS

[λ°±μ€€ 11657] νƒ€μž„λ¨Έμ‹  (JAVA)

WonderJay 2023. 1. 18. 12:24
728x90
λ°˜μ‘ν˜•
SMALL

문제

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

 

11657번: νƒ€μž„λ¨Έμ‹ 

첫째 쀄에 λ„μ‹œμ˜ 개수 N (1 ≤ N ≤ 500), λ²„μŠ€ λ…Έμ„ μ˜ 개수 M (1 ≤ M ≤ 6,000)이 주어진닀. λ‘˜μ§Έ 쀄뢀터 M개의 μ€„μ—λŠ” λ²„μŠ€ λ…Έμ„ μ˜ 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)κ°€ 주어진닀. 

www.acmicpc.net

N개의 λ„μ‹œκ°€ μžˆλ‹€. 그리고 ν•œ λ„μ‹œμ—μ„œ μΆœλ°œν•˜μ—¬ λ‹€λ₯Έ λ„μ‹œμ— λ„μ°©ν•˜λŠ” λ²„μŠ€κ°€ M개 μžˆλ‹€. 각 λ²„μŠ€λŠ” A, B, C둜 λ‚˜νƒ€λ‚Ό 수 μžˆλŠ”λ°, AλŠ” μ‹œμž‘λ„μ‹œ, BλŠ” λ„μ°©λ„μ‹œ, CλŠ” λ²„μŠ€λ₯Ό 타고 μ΄λ™ν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ΄λ‹€. μ‹œκ°„ Cκ°€ μ–‘μˆ˜κ°€ μ•„λ‹Œ κ²½μš°κ°€ μžˆλ‹€. C = 0인 κ²½μš°λŠ” μˆœκ°„ 이동을 ν•˜λŠ” 경우, C < 0인 κ²½μš°λŠ” νƒ€μž„λ¨Έμ‹ μœΌλ‘œ μ‹œκ°„μ„ λ˜λŒμ•„κ°€λŠ” κ²½μš°μ΄λ‹€.

1번 λ„μ‹œμ—μ„œ μΆœλ°œν•΄μ„œ λ‚˜λ¨Έμ§€ λ„μ‹œλ‘œ κ°€λŠ” κ°€μž₯ λΉ λ₯Έ μ‹œκ°„μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 λ„μ‹œμ˜ 개수 N (1 ≤ N ≤ 500), λ²„μŠ€ λ…Έμ„ μ˜ 개수 M (1 ≤ M ≤ 6,000)이 주어진닀. λ‘˜μ§Έ 쀄뢀터 M개의 μ€„μ—λŠ” λ²„μŠ€ λ…Έμ„ μ˜ 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)κ°€ 주어진닀. 

좜λ ₯

λ§Œμ•½ 1번 λ„μ‹œμ—μ„œ μΆœλ°œν•΄ μ–΄λ–€ λ„μ‹œλ‘œ κ°€λŠ” κ³Όμ •μ—μ„œ μ‹œκ°„μ„ λ¬΄ν•œνžˆ 였래 μ „μœΌλ‘œ 되돌릴 수 μžˆλ‹€λ©΄ 첫째 쀄에 -1을 좜λ ₯ν•œλ‹€. 그렇지 μ•Šλ‹€λ©΄ N-1개 쀄에 걸쳐 각 쀄에 1번 λ„μ‹œμ—μ„œ μΆœλ°œν•΄ 2번 λ„μ‹œ, 3번 λ„μ‹œ, ..., N번 λ„μ‹œλ‘œ κ°€λŠ” κ°€μž₯ λΉ λ₯Έ μ‹œκ°„μ„ μˆœμ„œλŒ€λ‘œ 좜λ ₯ν•œλ‹€. λ§Œμ•½ ν•΄λ‹Ή λ„μ‹œλ‘œ κ°€λŠ” κ²½λ‘œκ°€ μ—†λ‹€λ©΄ λŒ€μ‹  -1을 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1

3 4
1 2 4
1 3 3
2 3 -1
3 1 -2

예제 좜λ ₯ 1

4
3

예제 μž…λ ₯ 2

3 4
1 2 4
1 3 3
2 3 -4
3 1 -2

예제 좜λ ₯ 2

-1

예제 μž…λ ₯ 3

3 2
1 2 4
1 2 3

예제 좜λ ₯ 3

3
-1

  μ΅œλ‹¨ 거리λ₯Ό ꡬ해야 ν•˜λŠ”λ° 음의 κ°€μ€‘μΉ˜λ₯Ό 가진 edge κ°€ μ‘΄μž¬ν•˜λ©°, 음의 사이클 유무λ₯Ό νŒλ³„ν•΄μ•Ό ν•œλ‹€λ©΄ 벨만-ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•˜μ—¬ ν•΄κ²°ν•  수 μžˆλ‹€. 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(VE) μ΄λ―€λ‘œ μ‹œκ°„ μ œν•œ λ˜ν•œ λ„‰λ„‰ν•˜λ―€λ‘œ, 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ ν’€μ΄ν•˜μž.

 

  벨만-ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ€ Edge list λ₯Ό μ΄μš©ν•΄μ•Ό ν•œλ‹€. Node λŒ€μ‹  Edge λ₯Ό 가지고 graph λ₯Ό λ§Œλ“  λ‹€μŒμ—, λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ—μ„œ ν–ˆλ˜ κ·Έ λŠλ‚Œμ„ 가지고 κ΅¬ν˜„ν•΄μ£Όλ©΄ λœλ‹€.  λͺ¨λ“  에지λ₯Ό λ°©λ¬Έν•˜λ©°, start μ—μ„œ end 둜 λ‚˜μ•„κ°ˆ μ‹œμ— 기쑴에 κ΅¬ν•œ 거리보닀 μž‘λ‹€λ©΄ update ν•΄μ€€λ‹€. λ‹€λ§Œ μ€‘μš”ν•œ 것은 start node κ°€ λ°©λ¬Έν•˜μ§€ μ•Šμ•˜λ˜ node 에 λŒ€ν•΄μ„œλŠ” μ—…λ°μ΄νŠΈλ₯Ό μ§„ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것이닀.

 

  음수 κ°€μ€‘μΉ˜λ₯Ό 가진 edge κ°€ μ‘΄μž¬ν•¨μ— λ”°λΌμ„œ 음수 μ‚¬μ΄ν΄μ˜ μœ„ν—˜μ„±μ΄ μžˆλ‹€. 음수 μ‚¬μ΄ν΄μ΄λž€ 음수 κ°€μ€‘μΉ˜λ§Œ 가진 edge λ“€λ‘œ κ΅¬μ„±λœ 사이클을 μ˜λ―Έν•˜λ©°, ν•΄λ‹Ή path 둜 μ§„μž…ν•˜λŠ” 경우 λ¬΄ν•œνžˆ μ΅œλ‹¨κ±°λ¦¬κ°€ λ°œμ‚°ν•˜λŠ” 것이닀. (이거 λ•Œλ¬Έμ— dist 배열을 long 으둜 ν•΄μ€˜μ•Όν•œλ‹€.) 

 

  음수 사이클을 νŒλ³„ν•˜κΈ° μœ„ν•΄μ„œ, 벨만 - ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ„ ν•œλ²ˆ μˆ˜ν–‰ν•œ λ‹€μŒμ— ν•œ 번 더 μˆ˜ν–‰ν•΄μ€€λ‹€.(updateλŠ” ν•˜μ§€ μ•ŠλŠ”λ‹€.) κ·Έ κ³Όμ •μ—μ„œ 기쑴에 μ €μž₯된 μ΅œλ‹¨ 거리값이 변동이 생긴닀면 음의 사이클이 μžˆλŠ” 것이닀.

 

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

    static Edge[] graph;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer stk = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(stk.nextToken()); // λ…Έλ“œ 개수
        int m = Integer.parseInt(stk.nextToken()); // 엣지 개수
        graph = new Edge[m + 1];
        long[] dist = new long[n + 1];
        Arrays.fill(dist, Integer.MAX_VALUE);

        for (int i = 0; i < m; i++) {
            stk = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(stk.nextToken());
            int b = Integer.parseInt(stk.nextToken());
            int w = Integer.parseInt(stk.nextToken());
            graph[i] = new Edge(a, b, w);
        }

        // 벨만 - ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜ O(VE)
        dist[1] = 0;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < m; j++) {
                Edge now_edge = graph[j];
                if (dist[now_edge.st] != Integer.MAX_VALUE &&
                        dist[now_edge.end] > dist[now_edge.st] + now_edge.cost) {
                    dist[now_edge.end] = dist[now_edge.st] + now_edge.cost; // update
                }
            }
        }
        // 음수 사이클 νŒλ³„ν•˜κΈ°
        boolean cycle = false;
        for(int i = 0 ; i < m; i++){
            Edge now_edge = graph[i];
            if (dist[now_edge.st] != Integer.MAX_VALUE &&
                    dist[now_edge.end] > dist[now_edge.st] + now_edge.cost) {
                cycle = true;
            }
        }
        if(cycle){
            // 음수 사이클이 μ‘΄μž¬ν•˜λ©΄
            bw.write("-1\n");
        } else {
            // 음수 사이클이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄
            for(int i = 2; i <= n; i++){
                if(dist[i]==Integer.MAX_VALUE)
                    bw.write(-1+"\n");
                else bw.write(dist[i]+"\n");
            }
        }
        bw.flush();
        bw.close();
    }

    static class Edge {
        int st;
        int end;
        int cost;

        public Edge(int s, int e, int c) {
            this.st = s;
            this.end = e;
            this.cost = c;
        }
    }
}

728x90
λ°˜μ‘ν˜•
LIST
Comments