通信线路.java 2.3 KB
Newer Older
qq_36480062's avatar
c  
qq_36480062 已提交
1 2
package graph.复合单源最短路;

qq_36480062's avatar
c  
qq_36480062 已提交
3 4
import java.util.ArrayDeque;
import java.util.Arrays;
qq_36480062's avatar
c  
qq_36480062 已提交
5 6 7
import java.util.Scanner;

/**
qq_36480062's avatar
c  
qq_36480062 已提交
8
 * https://www.acwing.com/file_system/file/content/whole/index/content/533831/
qq_36480062's avatar
c  
qq_36480062 已提交
9
 * https://www.cnblogs.com/wulichenai/p/12694599.html
qq_36480062's avatar
c  
qq_36480062 已提交
10
 * 从a到b,路径的长度定义为第k+1大值
qq_36480062's avatar
c  
qq_36480062 已提交
11 12 13 14
 * 二分:定义在[0,1000001]区间性质为
 * 对于区间中的某一个点x
 * 求出1~N中最少经过几条长度大于x的边,假设最少经过y条,
 * (最少经过多少条大于x的边的数量是否小于等于k)
qq_36480062's avatar
c  
qq_36480062 已提交
15
 * 把边长大于x的看做1,否则看做0,非常难
qq_36480062's avatar
c  
qq_36480062 已提交
16
 * 用双端队列bfs
qq_36480062's avatar
c  
qq_36480062 已提交
17 18 19 20 21 22
 */
public class 通信线路 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
qq_36480062's avatar
c  
qq_36480062 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
        k = sc.nextInt();
        int a, b, c;
        while (m-- != 0) {
            a = sc.nextInt();
            b = sc.nextInt();
            c = sc.nextInt();
            add(a, b, c);
            add(b, a, c);
        }
        int l = 0, r = (int) (1e6 + 1);
        while (l < r) {
            int mid = l + r >> 1;
            if (check(mid)) r = mid;
            else l = mid + 1;
        }
        if (r == 1e6 + 1) r = -1;
        System.out.println(r);
    }

    private static boolean check(int bound) {
        Arrays.fill(st, false);
        Arrays.fill(dis, Integer.MAX_VALUE / 2);
        dis[1] = 0;
        q.add(1);
        while (!q.isEmpty()) {
            int t = q.poll();
            if (st[t]) continue;
            st[t] = true;
            for (int i = he[t]; i != 0; i = ne[i]) {
                int j = e[i], v = w[i] > bound ? 1 : 0;
                if (dis[j] > dis[t] + v) {
                    dis[j] = dis[t] + v;
                    if (v == 0) q.addFirst(j);
                    else q.addLast(j);
                }
            }
        }
        return dis[n] <= k;
qq_36480062's avatar
c  
qq_36480062 已提交
61 62
    }

qq_36480062's avatar
c  
qq_36480062 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    static void add(int a, int b, int c) {
        e[cnt] = b;
        w[cnt] = c;
        ne[cnt] = he[a];
        he[a] = cnt++;
    }

    static int n, m, N = 1010, M = 20010, cnt = 1, k;
    static int[] he = new int[N];
    static int[] ne = new int[M];
    static int[] w = new int[M];
    static int[] e = new int[M];
    static int[] dis = new int[N];
    static ArrayDeque<Integer> q = new ArrayDeque<Integer>();
    static boolean[] st = new boolean[N];

qq_36480062's avatar
c  
qq_36480062 已提交
79
}