通信线路
做法: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;
}