【二分/最短路】洛谷p1396 营救

P1396 营救

最小化最大值问题,无向图,可以用二分+BFS做,或者用最短路稍稍变形一下做

法一:堆优化dijkstra
统计每个点入边与出边的最大值,然后在这些最大值中找最小值存到dist数组中,最后dist[t]就是答案

// Problem: P1396 营救
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1396
// Memory Limit: 125 MB
// Time Limit: 1000 ms

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>

using namespace std;
using i64 = long long;
using PII = pair<int, int>;

const int N = 1e4 + 10, M = 2e4 * 2 + 10;

int n, m, s, t;
int h[N], w[M], e[M], ne[M], idx;
int st[N], dist[N];

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

void dijkstra(int sx)
{
    memset(st, 0, sizeof st);
    memset(dist, 0x3f, sizeof dist);

    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, sx});
    dist[sx] = 0;

    while (heap.size())
    {
        auto [x, y] = heap.top();
        heap.pop();

        if (st[y]) continue;
        st[y] = 1;

        for (int i = h[y]; i != -1; i = ne[i])
        {
            int j = e[i];
            int k = max(x, w[i]);
            // x是其他点到当前点的距离,w[i]是x到其他的距离
            // 相当于两条出边取权值大的那条
            if (dist[j] > k) // 然后在所有权值最大的边里找最小值
            {
                dist[j] = k;
                heap.push({dist[j], j});
            }
        }
    }
}

void solve()
{
    memset(h, -1, sizeof h);
    cin >> n >> m >> s >> t;
    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    dijkstra(s);
    cout << dist[t];
}

int main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int T = 1;
    while (T--) solve();
    return 0;
}

法二:待补充

posted @   Tshaxz  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
Language: HTML
点击右上角即可分享
微信分享提示