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");
}