CCA的图
题目链接:nowcoder 213878
到主站看:https://blog.csdn.net/weixin_43346722/article/details/112135711
题目大意
有一个图,每个边都有一个值,只有值在 L~R 之间的边才能存在。
你要让两个给定的点相连,而且要让 L 最大,R 在 L 最大的情况下尽可能小。
思路
首先,因为是去值在一个区间的值,那我们把边按这个值从小到大排个序。
题目说一定要让 L 最大,那我们可以先默认 R 是在最右边。
那我们就从最后往前枚举,每次多加一条边,一旦两个点相连,就立刻停止,这个时候的 L 点就是最后的 L 点。
至于怎么看两个点是否相连,我们可以用并查集。
然后接着它说要让在这个基础上 R 值尽可能小。
那我们就从 L 点开始向后枚举,每次加边,然后也是如果相连就停止,那这个时候的区间就是我们要的区间了。
同样,我们可以用并查集来判断两点是否相连。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
struct rode {
int x, y, w;
}a[3000001];
int n, m, s, t, fa[1000001], S, T, L, R;
bool cmp(rode x, rode y) {
return x.w < y.w;
}
int find(int now) {
if (fa[now] == now) return now;
return fa[now] = find(fa[now]);
}
void connect(int x, int y) {
int X = find(x), Y = find(y);
fa[X] = Y;
}
int main() {
scanf("%d %d %d %d", &n, &m, &s, &t);
for (int i = 1; i <= m; i++) {
scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].w);
}
sort(a + 1, a + m + 1, cmp);
for (int i = 1; i <= n; i++) fa[i] = i;
S = find(s);
T = find(t);
L = m + 1;
while (S != T) {
L--;
connect(a[L].x, a[L].y);
S = find(s);
T = find(t);
}//找到左边界的最大值
R = L - 1;
for (int i = 1; i <= n; i++) fa[i] = i;
S = find(s);
T = find(t);
while (S != T) {
R++;
connect(a[R].x, a[R].y);
S = find(s);
T = find(t);
}//在左边界最大的基础上,找到最小的右边界
printf("%d %d", a[L].w, a[R].w);
return 0;
} 
京公网安备 11010502036488号