在加权无向图上求出一条从1号结点到N号结点的路径,使路径上第K+1大的边权尽量小
二分+最短路算法

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define maxn 100010
using namespace std;
const int INF = 0x3f3f3f3f;
struct Node {
int p;
int len;
Node(int a, int b) :p(a), len(b) {}
};
vector<Node>G[maxn];
void insert(int be, int en, int len) {
G[be].push_back(Node(en, len));
}
bool operator <(const Node a, const Node b) {
return a.len > b.len;
}
int vis[maxn];
int dis[maxn];
int n, m, k;
int dijstra(int be, int range) {
memset(vis, 0, sizeof(vis));
memset(dis, INF, sizeof(dis));
priority_queue<Node>que;
que.push(Node(be, 0));
dis[be] = 0;
while (!que.empty()) {
Node ans = que.top();
que.pop();
if (vis[ans.p]) continue;
vis[ans.p] = 1;
int x = ans.p;
for (int i = 0; i < G[x].size(); i++) {
int p = G[x][i].p;
int len;
if (G[x][i].len >= range) len = 1;
else len = 0;
if (dis[p] > dis[x] + len) {
dis[p] = dis[x] + len;
que.push(Node(p, dis[p]));
}
}
}
return dis[n];
}
int check(int mid) {
int len = dijstra(1, mid);
if (len >= k + 1) return 0;
else return 1;
}
int main() {
int be, en, len;
scanf("%d%d%d", &n, &m, &k);
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &be, &en, &len);
insert(be, en, len);
insert(en, be, len);
}
int l = 0;
int r = 10000000;
int mid;
int flag = 0;
while (r - l > 1) {
mid = (r + l) / 2;
if (check(mid)) {//往小了压
r = mid;
}
else {
l = mid ;
}
}
if (r == 10000000) cout << "-1" << endl;
else cout << l << endl;
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号