通信线路【最短路】

通信线路

题目

做法:Dijkstra + 二分,题目要求求出第k+1条路的花费,我们把值大于x且不超过k条边的情况进行二分,图片最后是求最短路的同时求出来有几条大于x的边(同时咋就写成宇宙了呜呜呜文件还没保存)通信线路【最短路】
具体代码如下

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010, M = 20010;

int n, m, k;
int h[N], e[M], w[M], ne[M], idx;
int dis[N];
bool st[N];

void add(int a, int b, int c){
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

bool check(int bound){
    memset(dis, 0x3f, sizeof dis);
    memset(st, 0, sizeof st);
    priority_queue<PII, vector<PII>, greater<PII> >heap;
    heap.push({0, 1});
    dis[1] = 0;
    
    while(heap.size()){
        PII t = heap.top();
        heap.pop();
        int ver = t.y;
        if(st[ver]) continue;
        st[ver] = true;
        
        for(int i=h[ver]; ~i; i=ne[i]){
            int j = e[i], v = w[i] > bound;//w[i]大于bound我们就把它设置为1,小于就设置为0
            if(dis[j] > dis[ver] + v){
                dis[j] = dis[ver] + v;
                heap.push({dis[j], j});
            }
            
        }
    }
    return dis[n] <= k;
}

int main(){
    
    memset(h, -1, sizeof h);
    cin >> n >> m >> k;
    
    while(m--){
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    
    int l = 0, r = 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;
    cout << r << endl;
    
    return 0;
}
上一篇:【数据结构】可持久化线段树


下一篇:linux常用命令