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; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
· Android编译时动态插入代码原理与实践
· 解锁.NET 9性能优化黑科技:从内存管理到Web性能的最全指南
· 一天 Star 破万的开源项目「GitHub 热点速览」
· 别再堆文档了,大模型时代知识库应该这样建
· 瞧瞧别人家的日期处理,那叫一个优雅!
· 使用TypeScript开发微信小程序(云开发)-入门篇
· 没几个人需要了解的JDK知识,我却花了3天时间研究