Telephone Line S
题目大意:
首先你有一张图,问你从到
的路径中第
条最大的边最小有多大
分析:
这个题很显然是可以二分答案的
但是我们考虑换一种做法:分层图
那么就是跨层的时候让其代价为,那么一共就有
层图
在跑一个类似最短路的东西就可以了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
const int inf = 0x7f7f7f7f;
inline int __read()
{
int x(0), t(1);
char o (getchar());
while (o < '0' || o > '9') {
if (o == '-') t = -1;
o = getchar();
}
for (; o >= '0' && o <= '9'; o = getchar()) x = (x << 1) + (x << 3) + (o ^ 48);
return x * t;
}
int n, p, k, cur;
int head[maxn], edge[maxn], __prev[maxn], cost[maxn];
inline void _addedge(int u, int v, int w)
{
__prev[++cur] = head[u];
head[u] = cur;
edge[cur] = v;
cost[cur] = w;
}
inline void __addedge(int u, int v, int w)
{
_addedge(u, v, w), _addedge(v, u, w);
}
int dis[maxn];
bool vis[maxn];
inline void SPFA()
{
memset (dis, 0x7f, sizeof dis);
deque <int> Q;
Q.push_back(1);
dis[1] = 0;
while (!Q.empty()) {
int now = Q.front();
Q.pop_front();
vis[now] = 0;
for (int i = head[now]; i; i = __prev[i]) {
const int v = edge[i];
if (dis[v] <= max(dis[now], cost[i])) continue;
dis[v] = max(dis[now], cost[i]);
if (vis[v]) continue;
if (Q.empty() || dis[v] <= dis[Q.front()]) Q.push_front(v);
else Q.push_back(v);
vis[v] = 1;
}
}
if (dis[n * (k + 1)] == inf) puts("-1");
else printf ("%d\n", dis[n * (k + 1)]);
}
int main()
{
n = __read(), p = __read(), k = __read();
while (p--) {
int u = __read(), v = __read(), a = __read();
__addedge(u, v, a);
for (int i = 1; i <= k; ++i) {
__addedge(i * n + u, i * n + v, a);
_addedge((i - 1) * n + u, i * n + v, 0);
_addedge((i - 1) * n + v, i * n + u, 0);
}
}
SPFA();
system("pause");
} 
京公网安备 11010502036488号