P1948 [USACO08JAN]Telephone Lines S
P1948 [USACO08JAN]Telephone Lines S
这种题显然考虑二分(有条件最大值最小(确信)。
然后发现可以二分,那么直接二分跑dijk/spfa/0-1bfs。
为啥啊,因为,肯定是要选够 \(K\) 条的。所以我们二分一下第 \(K-1\) 条边长。大于的都设 \(1\) 小于等于的都设 \(0\)。分别代表需要一个代价去免费它或者需要自己付款。
然后就是答案了。
/*
Name:
Author: Gensokyo_Alice
Date:
Description:
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6+10, INF = 0x3f3f3f3f3f3f3f3f;
ll head[MAXN], cnt = -1, N, M, KK, hd[MAXN], ck = -1, dis[MAXN], vis[MAXN];
struct edge {
ll nt, to, v;
} E[MAXN], K[MAXN];
struct heap {
ll now, val;
heap(){}
heap(ll _now, ll _val): now(_now), val(_val) {}
friend bool operator < (heap a, heap b) {return a.val > b.val;}
};
void add_K(ll, ll, ll);
void add(ll, ll, ll);
ll check(ll);
int main() {
memset(hd, -1, sizeof(hd));
scanf("%lld%lld%lld", &N, &M, &KK);
for (ll i = 1, x, y, v; i <= M; i++) {
scanf("%lld%lld%lld", &x, &y, &v);
add_K(x, y, v);
add_K(y, x, v);
}
ll l = 0, r = MAXN, ans = -1;
while (l <= r) {
ll mid = (l + r) >> 1;
if (check(mid) <= KK) {
r = mid - 1;
ans = mid;
} else l = mid + 1;
}
printf("%lld", ans);
return 0;
}
ll check(ll tem) {
for (ll i = 0; i < N + 10; i++) head[i] = -1;
for (ll i = 1; i <= N; i++) {
for (ll j = hd[i]; ~j; j = K[j].nt) {
ll v = K[j].to;
add(i, v, K[j].v > tem);
}
}
for (ll i = 0; i < N + 10; i++) dis[i] = INF, vis[i] = 0;
vis[1] = 1, dis[1] = 0;
priority_queue <heap> q;
q.push(heap(1, 0));
while (!q.empty()) {
heap nt = q.top(); q.pop();
if (nt.val > dis[nt.now]) continue;
for (ll i = head[nt.now]; ~i; i = E[i].nt) {
ll v = E[i].to;
if (dis[v] > dis[nt.now] + E[i].v) {
dis[v] = dis[nt.now] + E[i].v;
q.push(heap(v, dis[v]));
}
}
}
return dis[N];
}
void add(ll x, ll y, ll v) {
cnt++;
E[cnt].v = v;
E[cnt].to = y;
E[cnt].nt = head[x];
head[x] = cnt;
}
void add_K(ll x, ll y, ll v) {
ck++;
K[ck].v = v;
K[ck].to = y;
K[ck].nt = hd[x];
hd[x] = ck;
}
希望我们都有一个光明的未来