hiho_1139_二分+bfs搜索

题目

    给定N个点和M条边,从点1出发,到达点T。寻找路径上边的个数小于等于K的路径,求出所有满足条件的路径中最长边长度的最小值。 
题目链接:二分 
    最小化最大值,考虑采用二分搜索。对所有的边长进行排序,二分,对每次选择的边长,判断是否存在一条路径满足路径上所有的边长度均小于等于该边长,且路径中的边的个数小于等于K。 
    在判断路径是否存在的时候,使用BFS搜索,因为BFS用于寻找最短(边的个数最少)路径。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
using namespace std;
struct Edge{
    int to;
    int dist;
    int next;
};
//边的个数,开始的时候数组开的长度为 100005, hihocoder上提示 TLE,实际应该为 RE!!!
//数组开到 200005,就AC了
Edge gEdges[200005];
int gHead[10005];
bool gVisited[10005];
int gEdgeIndex;
void Init(){
    gEdgeIndex = 0;
    memset(gEdges, -1, sizeof(gEdges));
    memset(gHead, -1, sizeof(gHead));
    memset(gVisited, false, sizeof(gVisited));
}
void InsertEdge(int u, int v, int d){
    int e = gEdgeIndex++;
    gEdges[e].to = v;
    gEdges[e].dist = d;
    gEdges[e].next = gHead[u];
    gHead[u] = e;
}
struct Node{
    int id;
    int step;
    Node(int i = 0, int s = 0) :id(i), step(s){};
};
//BFS 搜索,寻找从点1到达点boss的路径,要求路径上的所有边的长度都小于等于max_d,且路径长度最大为k
//判断能否找到满足要求的路径
bool Arrive2Boss(int boss, int max_d, int k){
    queue<Node> Q;
    Node node(1, 1);
    Q.push(node);
    memset(gVisited, false, sizeof(gVisited));
    while (!Q.empty()){
        node = Q.front();
        Q.pop();
        if (node.id == boss)
            return true;
        if (gVisited[node.id])
            continue;
        gVisited[node.id] = true;
        for (int e = gHead[node.id]; e != -1; e = gEdges[e].next){
            int v = gEdges[e].to;
            if (!gVisited[v] && gEdges[e].dist <= max_d && node.step <= k){
                Q.push(Node(v, node.step + 1));
            }
        }
    }
    return false;
}
int edges_len[100005];
int main(){
    int N, M, K, T, u, v, d;
    Init();
    scanf("%d %d %d %d", &N, &M, &K, &T);
    for (int i = 0; i < M; i++){
        scanf("%d %d %d", &u, &v, &d);
        InsertEdge(u, v, d);
        InsertEdge(v, u, d);
        edges_len[i] = d;
    }
    //对路径进行排序
    sort(edges_len, edges_len + M);
    int beg = 0, end = M;
    //二分查找
    while (beg < end){
        int mid = (beg + end) / 2;
        int max_d = edges_len[mid];
        if (Arrive2Boss(T, max_d, K)){
            end = mid;
        }
        else
            beg = mid + 1;
    }
    int result = edges_len[beg];
    printf("%d\n", result);
    return 0;
}

 

posted @   农民伯伯-Coding  阅读(170)  评论(0)    收藏  举报
编辑推荐:
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
· Android编译时动态插入代码原理与实践
· 解锁.NET 9性能优化黑科技:从内存管理到Web性能的最全指南
阅读排行:
· 一天 Star 破万的开源项目「GitHub 热点速览」
· 别再堆文档了,大模型时代知识库应该这样建
· 瞧瞧别人家的日期处理,那叫一个优雅!
· 使用TypeScript开发微信小程序(云开发)-入门篇
· 没几个人需要了解的JDK知识,我却花了3天时间研究
点击右上角即可分享
微信分享提示