题目描述
给定一个 个点, 条边的无向图,每条边有一个权值。
问是否存在一条从 1 到 的路径使得路径上的权值的最大值最小,求出这个最大值。
如果 1 号点和 号点不连通,则输出 -1。
注意:请勿采用递归形式的DFS,谨防爆栈。
输入格式
第一行两个整数 ,。
接下来 行,每行三个整数 表示在 和 之间存在一条权值为 的无向边。
输出格式
一个整数表示答案。
样例输入1
4 5
1 2 2
2 3 3
2 3 2
3 4 1
1 4 5
样例输出1
2
样例输入2
3 2
1 2 1
1 2 5
样例输出2
-1
思路
首先,定义一个结构体Sedge,用来存储边的终点和权重。然后定义一个全局的边数组edge,用来存储图的信息。
在主函数中,先从输入中读取节点数量和边的数量,然后读取每条边的信息,包括起点、终点和权重,并将这些信息存储在edge数组中。
接下来使用二分查找的方法来寻找满足条件的权重上限。定义了一个check函数,这个函数接受一个参数,代表权重的上限。然后使用DFS的方法来遍历图,如果存在一条从起点到终点的路径,路径上所有边的权重都不超过这个上限,那么就返回true,否则返回false。在DFS的过程中,使用了一个栈来存储待遍历的节点,使用一个bitset来记录已经遍历过的节点。
在主函数中,使用二分查找的方法来寻找满足条件的权重上限。初始时,上限设置为10000,下限设置为0。然后在下限和上限之间进行二分查找,每次取中点作为权重上限,然后调用check函数来检查是否存在满足条件的路径。如果存在,那么说明这个权重上限可能偏大,需要将上限设置为中点;如果不存在,那么说明这个权重上限偏小,需要将下限设置为中点。如此反复,直到找到满足条件的最小的权重上限。
最后,再次调用check函数来检查是否存在一条从起点到终点的路径,如果存在,那么输出这个权重上限,否则输出-1。
AC代码
#include <algorithm>
#include <bitset>
#include <iostream>
#include <stack>
#include <vector>
#define AUTHOR "HEX9CF"
using namespace std;
using ll = long long;
const int N = 1e6 + 7;
struct Sedge {
int to;
int w;
};
int n, m;
vector<Sedge> edge[N];
bool check(int x) {
stack<int> stk;
bitset<N> vis;
vis.reset();
stk.push(1);
while (stk.size()) {
int t = stk.top();
stk.pop();
vis[t] = 1;
for (const auto i : edge[t]) {
if (vis[i.to] || i.w > x) {
continue;
}
stk.push(i.to);
}
}
return vis[n];
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
edge[u].push_back({v, w});
edge[v].push_back({u, w});
}
int l = 0;
int r = 1e4;
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
// 能到达,mid偏大
r = mid;
} else {
// 不能到达,mid偏小
l = mid;
}
}
// 检查是否联通
cout << (check(r) ? r : -1) << endl;
return 0;
}