信奥赛C++提高组csp-s之并查集(案例实践)2

信奥赛C++提高组csp-s之并查集(案例实践)2

题目描述

妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了 t t t 区,而自己在 s s s 区。

该市有 m m m 条大道连接 n n n 个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从 s s s 至 t t t 的路线,使得经过道路的拥挤度最大值最小。

输入格式

第一行有四个用空格隔开的 n n n, m m m, s s s, t t t,其含义见【题目描述】。

接下来 m m m 行,每行三个整数 u , v , w u, v, w u,v,w,表示有一条大道连接区 u u u 和区 v v v,且拥挤度为 w w w。

两个区之间可能存在多条大道

输出格式

输出一行一个整数,代表最大的拥挤度。

输入输出样例 1
输入 1
复制代码
3 3 1 3
1 2 2
2 3 1
1 3 3
输出 1
复制代码
2
数据规模与约定
  • 对于 30 % 30\% 30% 的数据,保证 n ≤ 10 n\leq 10 n≤10。
  • 对于 60 % 60\% 60% 的数据,保证 n ≤ 100 n\leq 100 n≤100。
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 10 4 1 \leq n\leq 10^4 1≤n≤104, 1 ≤ m ≤ 2 × 10 4 1 \leq m \leq 2 \times 10^4 1≤m≤2×104, w ≤ 10 4 w \leq 10^4 w≤104, 1 ≤ s , t ≤ n 1 \leq s, t \leq n 1≤s,t≤n。且从 s s s 出发一定能到达 t t t 区。
样例输入输出 1 解释

小明的妈妈要从 1 1 1 号点去 3 3 3 号点,最优路线为 1 1 1-> 2 2 2-> 3 3 3。

代码实现

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n, m, s, t, ans; 
struct edge {
    int x, y, w;  // 边的两个端点和拥挤度
}a[20010];

int fa[10010];  // 并查集数组

// 并查集查找根节点(带路径压缩)
int find(int x) {
    if (fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}

// 并查集合并
void unionSet(int x, int y) {
    int rootx = find(x);
    int rooty = find(y);
    if (rootx == rooty) return;
    fa[rooty] = rootx; 
}

// 检查当拥挤度限制为mid时,s和t是否连通
bool check(int mid) {
    // 初始化并查集
    for (int i = 1; i <= n; i++) fa[i] = i;
    
    // 遍历所有边,将拥挤度不超过mid的边加入图中
    for (int i = 1; i <= m; i++) {
        if (a[i].w <= mid) {
            unionSet(a[i].x, a[i].y);
        }
    }
    
    // 检查s和t是否连通
    return find(s) == find(t);
}

int main() {
    cin >> n >> m >> s >> t;
    
    // 读入所有边
    for (int i = 1; i <= m; i++) {
        cin >> a[i].x >> a[i].y >> a[i].w;
    }
    
    // 二分查找最小的最大拥挤度
    int l = 1, r = 1e4;  // 拥挤度范围是1-10000
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(mid)) {
            // 如果当前mid能满足条件,尝试更小的值
            ans = mid;
            r = mid - 1;
        } else {
            // 如果当前mid不能满足条件,需要更大的值
            l = mid + 1;
        }
    }
    
    cout << ans;
    return 0;
}

功能分析

这个程序解决的是"最小化路径上最大拥挤度"的问题,采用了二分答案 + 并查集的方法。

核心思路
  1. 问题转化:寻找从s到t的一条路径,使得路径上所有边的最大拥挤度最小
  2. 二分策略:对拥挤度的可能取值进行二分,检查某个拥挤度限制下s和t是否连通
  3. 连通性检查:使用并查集来高效判断在只使用拥挤度不超过某值的边时,s和t是否连通
算法步骤
  1. 输入处理:读取图的节点数、边数、起点和终点,以及所有边的信息

  2. 二分查找

    • 左边界l=1,右边界r=10000(题目保证w≤10000)
    • 对于每个中间值mid,检查在只使用拥挤度≤mid的边时,s和t是否连通
  3. 连通性检查(check函数)

    • 初始化并查集,每个节点自成一个集合
    • 遍历所有边,将拥挤度不超过mid的边连接的两个节点合并
    • 最后检查s和t是否在同一个集合中
  4. 结果输出:输出满足条件的最小拥挤度

各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}
  • 一、CSP信奥赛C++通关学习视频课:
    • C++语法基础
    • C++语法进阶
    • C++算法
    • C++数据结构
    • CSP信奥赛数学
    • CSP信奥赛STL
  • 二、CSP信奥赛C++竞赛拿奖视频课:
    • 信奥赛csp-j初赛高频考点解析
    • CSP信奥赛C++复赛集训课(12大高频考点专题集训)
  • 三、csp高频考点知识详解及案例实践:
    • CSP信奥赛C++之动态规划
    • CSP信奥赛C++之标准模板库STL
    • 信奥赛C++提高组csp-s知识详解及案例实践
  • 四、考级、竞赛刷题题单及题解:
    • GESP C++考级真题题解
    • CSP信奥赛C++初赛及复赛高频考点真题解析
    • CSP信奥赛C++一等奖通关刷题题单及题解

详细内容:

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转


2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
满天星83035771 天前
【C++】特殊类设计
c++·windows
Ljubim.te1 天前
inline介绍,宏定义的注意事项以及nullptr
c语言·开发语言·c++
苦藤新鸡1 天前
6.三数之和
c语言·c++·算法·力扣
Frank_refuel1 天前
C++之内存管理
java·数据结构·c++
leiming61 天前
c++ qt开发第一天 hello world
开发语言·c++·qt
@小码农1 天前
6547网:202512 GESP认证 C++编程 一级真题题库(附答案)
java·c++·算法
TDengine (老段)1 天前
TDengine C/C++ 连接器入门指南
大数据·c语言·数据库·c++·物联网·时序数据库·tdengine
菜鸟233号1 天前
力扣343 整数拆分 java实现
java·数据结构·算法·leetcode
vyuvyucd1 天前
C++ vector容器完全指南
c++