首页 > 试题广场 >

修复公路

[编程题]修复公路
  • 热度指数:104 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}某国在一场规模空前的大灾害过后,连接所有城市的公路都遭到了损坏而无法通车。政府派人修复这些公路。

\hspace{15pt}给出该国的城市数 N 和公路数 M,公路是双向的。并告诉你每条公路的连着哪两个城市以及什么时候能修完这条公路。询问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)。

输入描述:
\hspace{15pt}输入的第一行包含两个正整数 N\left(1 \leqq N \leqq 10^3\right),M\left(1 \leqq M \leqq 10^5\right),分别表示某国的城市数和公路数。
 
\hspace{15pt}接下来 M 行,每行三个正整数 x,y\left( 1 \leqq x,y \leqq N\right),t \left( 1 \leqq t \leqq 10^5 \right),表示存在一条连着 x,y 两个城市的,需要花费时间 t 来完成修复的公路。


输出描述:
\hspace{15pt}如果全部公路修复完毕仍然存在两个城市无法通车,则输出 -1,否则输出最早什么时候可以使得任意两个城市都能够通车。
示例1

输入

4 4
1 2 6
1 3 4
1 4 5
4 2 3

输出

5
第一次刷并查集和图论的题目,真不习惯,但是用这么复杂的循环和5M内存竟然也能通过,可能图就是复杂度高吧
```cpp
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> father;

int find(int u) {

int root_u = father[u];

if (root_u == u) return u;
else {
return find(root_u);
}
}

void join(int u, int v) {

int root_u = find(u);
int root_v = find(v);

if (root_u == root_v) return;

father[root_u] = root_v;

}

int main() {

int n, m;

cin >> n >> m;

vector<vector<int>> roads {};

father = vector<int>(n + 1, 0);

for (int i = 0; i < n + 1; i++) {
father[i] = i;
}

while (m--) {
int x, y, t;
cin >> x >> y >> t;
roads.push_back({x, y, t});
}

sort(begin(roads), end(roads), [](vector<int>& a, vector<int>& b) {
return a[2] < b[2];
});

int time = 0;
bool flag = false;

for (int i = 0; i < roads.size(); i++) {
auto& road = roads[i];

time += road[2] - time;

join(road[0], road[1]);


int elem = find(1);
flag = true;
for (int i = 1; i < n + 1; i++) {
if (elem != find(i)) {
flag = false;
break;
}
}

if (flag) {
break;
}
}
if (flag)
cout << time << endl;
else
cout << -1 << endl;
```


发表于 2025-10-10 09:18:26 回复(0)