[并查集]HAOI2006 旅行

本文介绍了一种寻找两点间最舒适路径的算法实现,通过排序和并查集的方法,在给定的景点和道路中找到最大最小速度比最小的路径。

题目描述
Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。Z小镇附近共有N个景点(编号为1,2,3,…,N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。速度变化太快使得游客们很不舒服,因此从一个景点前往另一个景点的时候,大家都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。

Input

第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。
最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。

Output

如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。

1<N<=500
1<=x,y<=N,0<v<30000,x≠y
0<M<=5000

分析
这题看了一下,数据不大,可以m^2枚举。
但是如何判断是最大最小比呢?我想到了排序
排序以后,就很容易了,可是还有一个问题,如果要查找是否合并的话,要一个m^2的邻接矩阵,肯定MLE的
并查集可解此问题。
1、排序(由小到大)
2、每次枚举一个景点,当并查集发现起点与终点已经连接以后,退出第二层枚举(或者所有点都枚举一遍仍无法连接可以退出)
3、把最大值和最小值的比值与原最大值和最小值的比值对比,更新
4、欧几里德约分即可
(温馨提示,比值等式列为a:b=c:d,为求精确度我转化为乘法ad=bc)

#include <iostream>
#include <cstdio>
using namespace std;
int n,m,a[5001][3],i,j,f[501],mx,mn,s,t;
void qs(int l,int h)
{
    int i=l,j=h,mid=a[(l+h)/2][2],t;
    if (l>=h) return;
    do
    {
        while (a[i][2]<mid) i++;
        while (a[j][2]>mid) j--;
        if (i<=j)
        {
            t=a[i][0];a[i][0]=a[j][0];a[j][0]=t;
            t=a[i][1];a[i][1]=a[j][1];a[j][1]=t;
            t=a[i][2];a[i][2]=a[j][2];a[j][2]=t;
            i++;j--;
        }
    }
    while (i<=j);
    qs(i,h);
    qs(l,j);
}
int fin(int x)
{
    int i=x,root;
    while (f[i]!=i)
    i=f[i];
    root=i;
    i=x;
    while (f[i]!=i)
    {
        f[i]=root;
        i=f[i];
    }
    return root;
}
void uni(int x,int y)
{
    int i=fin(x),j=fin(y);
    f[i]=f[j];
}
int gcd(int a,int b)
{
    if (b==0) return a;
    return gcd(b,a%b);
}
int main()
{
    scanf("%d%d",&n,&m);
    for (i=1;i<=m;i++)
    scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
    scanf("%d%d",&s,&t);
    qs(1,m);
    mx=5000;mn=1;
    for (i=1;i<=m;i++)
    {
        for (j=1;j<=n;j++) f[j]=j;
        j=i-1;
        while (j<=m&&fin(s)!=fin(t))
        {
            j++;
            uni(a[j][0],a[j][1]);
        }
        if (fin(s)!=fin(t)) 
        break;
        if (a[j][2]*mn<a[i][2]*mx)
        {
            mx=a[j][2];
            mn=a[i][2];
        }
    }
    if (mx==5000)
    {
        printf("IMPOSSIBLE");
        return 0;
    }
    int q=gcd(mx,mn);
    mx/=q;mn/=q;
    if (mx%mn==0)
    printf("%d",mx/mn);
    else
    printf("%d/%d",mx,mn);
}
内容概要:本文介绍了基于贝叶斯优化的CNN-LSTM混合神经网络在时间序列预测中的应用,并提供了完整的Matlab代码实现。该模型结合了卷积神经网络(CNN)在特征提取方面的优势与长短期记忆网络(LSTM)在处理时序依赖问上的强大能力,形成一种高效的混合预测架构。通过贝叶斯优化算法自动调参,提升了模型的预测精度与泛化能力,适用于风电、光伏、负荷、交通流等多种复杂非线性系统的预测任务。文中还展示了模型训练流程、参数优化机制及实际预测效果分析,突出其在科研与工程应用中的实用性。; 适合人群:具备一定机器学习基基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)础和Matlab编程经验的高校研究生、科研人员及从事预测建模的工程技术人员,尤其适合关注深度学习与智能优化算法结合应用的研究者。; 使用场景及目标:①解决各类时间序列预测问,如能源出力预测、电力负荷预测、环境数据预测等;②学习如何将CNN-LSTM模型与贝叶斯优化相结合,提升模型性能;③掌握Matlab环境下深度学习模型搭建与超参数自动优化的技术路线。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注贝叶斯优化模块与混合神经网络结构的设计逻辑,通过调整数据集和参数加深对模型工作机制的理解,同时可将其框架迁移至其他预测场景中验证效果。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值