【每日一题】1月15日题目精讲

题号 NC19963
名称 旅行
来源 [HAOI2006]
戳我进入往期每日一题汇总贴~
往期每日一题二期题单

图片说明

如果你在题库做题时遇到了喜欢的题目,欢迎推荐给邓老师~ 点击查看详情
欢迎给每日一题投稿,投稿需要提供牛客题库里的题目+题解 投稿有牛币奖励,可发站内信给王清楚或联系QQ 234186389
每日一题QQ群:659028468

题解

作者 YangYL°

前置知识

这道题的解法为:并查集 + 排序 + 二分

难度: 3 星

主要做法

首先考虑如何判断无解,很明显,无解的情况就是无论怎么样都不能从起点到终点,那么就是起点和终点在整个图中不连通,那么这种情况下输出"IMPOSSIBLE",其余情况皆有解。

题目要求最大边与最小边的比值最小,所以我们不妨可以 枚举最小边 最大边,笔者选择的是枚举最小边。

因为此刻我们通过枚举已经确定的最小边,所以我们现在要最小化最大边

在使用 的时候,加入的最后一条边就是整个生成树里面最大的一条边,在这道题里面最后加入的一条边的性质是什么呢?

不难想到加入的最后一条边一定是加入它之后使得终点和起点都联通了,这时候它就是最后一条边。

于是我们想到用同样的思路,先把边排序,然后从小到大枚举每一条边作为最小边的情况,然后不停的加边权大于等于它的边,倘若起点与终点已经联通,我们就停止加边,因为是 无向图,判断连通性用并查集即可。

然后用枚举到的最大边除以当前枚举到的最小边去更新答案,如果比答案更优,就记录下此时的最大边权和最小比权。

时间复杂度是:O( * 反阿克曼函数)。

如何比较两个分数的大小?

众所周知:假如 : 都大于

那么

所以得到:

是因为这里的边权较小,并不需要开,所以交叉相乘更方便。

对于此题的分析到此结束。

Code

#include <bits/stdc++.h>
using namespace std;

int n , m , cnt = 0,Ansa = 300001 ,Ansb = 1;//这个初值很讲究,不能爆int,也要恰好大于30000,于是就有了这个初值
int fa[505],s,t;

struct Edge {
    int from,to,w;
    bool operator < (const Edge& E) { return E.w > w;}
    void add(int u,int v, int W) { from = u , to = v , w = W; return ;}
} edge[10005];//双向边,记得开两倍空间

int find(int x) {
    if(fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];//路径压缩版的并查集
}

bool pd(int u,int v) {
    if(find(u) == find(v)) return 1;//判断u,v是否在同一个并查集中
    return 0;
}

void reset() {
    for(int i = 1 ; i <= n ; i ++) fa[i] = i;//重置并查集
    return ;
}

int main() {
    cin >> n >> m;
    reset();
    for(int i = 1 ; i <= m ; i ++) {
        int u , v , w;
        cin >> u >> v >> w;
        edge[++cnt].add(u,v,w);
        edge[++cnt].add(v,u,w);
        fa[find(u)] = find(v);//先合并,为了判断s,t的连通性
    }
    cin >> s >> t;
    if(!pd(s,t)) {
        cout << "IMPOSSIBLE";//如果在图中不连通,肯定无解
        return 0;
    }
    if(s == t){ cout << 0 ;return 0; }
    sort(edge + 1 , edge + 1 + cnt);//按照边权从小到大排序
    for(int i = 1 ; i < cnt ; i ++) { //枚举最小边
        int k,flag = 0;reset();
        for(int j = i ; j <= cnt ; j ++) {
            if(pd(s,t)) {flag = 1 ; break;}
            k = j;
            fa[find(edge[j].from)] = find(edge[j].to);
        }
        if(!flag) break;//假设已经不能用大于等于这个最小值的边权的边使得起点和终点联通,就没必要枚举了。
        int a = Ansa , b = Ansb , c = edge[k].w , d = edge[i].w;
        if(a * d - b * c > 0)//对应上面的柿子
        Ansa = edge[k].w , Ansb = edge[i].w;
    }
    if(Ansa % Ansb == 0) cout << Ansa / Ansb;//恰好能够整除按照题目要求是输出一个整数
    else cout << Ansa / __gcd(Ansa,Ansb) << "/" << Ansb / __gcd(Ansa,Ansb);//计算答案
    return 0;
}

欢迎各位大佬来做题写题解,也欢迎大家踊跃在当日讨论贴中提问!

活动奖励:

在牛客博客中写出题解,并回复地址
审核通过可获得(依据题目难度和题解的内容而定)

本道题目1月22日中午12:00之前写的题解有获得牛币资格~

.牛币兑换中心

牛客博客开通方式

  1. 如何开通牛客博客:https://www.nowcoder.com/discuss/202952
  2. 如何使用博客搬家功能:进入博客--->设置--->底部博客搬家
  3. 如果你对牛客博客有任何意见或建议:牛客博客意见反馈专贴
全部评论
behind review i will come back.
2 回复 分享
发布于 2021-01-14 11:29
占楼🤣
1 回复 分享
发布于 2021-01-14 10:48
https://blog.nowcoder.net/n/9ea34cd17cf74a80b84ea5e9925fd4b8
1 回复 分享
发布于 2021-01-14 10:54
qcjj 保佑我 ak 数据结构
1 回复 分享
发布于 2021-01-14 12:44
https://blog.nowcoder.net/n/cbd0752351744f37aa647c4a60d80c23
点赞 回复 分享
发布于 2021-01-14 14:19
https://blog.nowcoder.net/n/588f4f842b5e4f6ba1f54bb90a20ac57
点赞 回复 分享
发布于 2021-01-14 16:07
https://blog.nowcoder.net/n/2755152a8cdc4016909fa8fb411057b0
点赞 回复 分享
发布于 2021-01-14 16:38
https://blog.nowcoder.net/n/99c4a21bde09433eba98ff10979ab3c7
点赞 回复 分享
发布于 2021-01-14 19:56
https://blog.nowcoder.net/n/8b81ce95f1f346a999909f0d079799f5
点赞 回复 分享
发布于 2021-01-15 17:42
https://blog.nowcoder.net/n/475ee090d4a94491a92c7f12f7ac4f96
点赞 回复 分享
发布于 2021-01-17 11:14
https://blog.nowcoder.net/n/c40b405aaff74695acfedfec40616ff9
点赞 回复 分享
发布于 2021-01-20 21:46

相关推荐

2024-12-11 09:14
门头沟学院 软件测试
2025毕业等一个offer:女生终于扳回一局
点赞 评论 收藏
分享
2024-12-31 11:37
已编辑
腾讯_前端开发
秋招结束,做了一个与牛客主流想法完全相反的决定。bg写在开头:本人是电气专业的211本硕,研0开始零基础转前端。历时一年半,刷了三段实习,暑期在🐧厂实习,最后顺利转正了,开的价位也挺满意的,不是白菜。其实家里面非常非常希望我去电网,几乎是从高中开始就帮我选好了这条路。所以家里的意见也一直是我转码路上相当大的阻力,尤其是今年大大小小的吵了很多架。最终也是拗不过我自己的想法,爸妈看到我拿到很好的offer以后,也终于尊重了我的选择。简单说说心理历程:大学期间没有想太多,一直在折腾七七八八的副业。作为期末冲刺型选手,保研了本校本专业。大四毕业做了算法相关的毕设,才发现编程没有想象中的难。于是研0开始考虑别的职业选择。转码的过程不展开多说,也是扎扎实实学了很久。如果也有非科班零基础自学的朋友想看经验分享我也可以后续展开写写。没选电网会不会后悔?我个人觉得,不会。做出这个选择我几乎没有一丝犹豫。1.&nbsp;电网最大的优势就是稳定性,而这恰巧是我最不看重的点。现在不会失业不代表十年后二十年后不会失业;&nbsp;世界局势随时可能发生变化,进电网也并非一劳永逸。个人认为这个世界上没有永远稳定的工作,只有稳定的个人能力。2.&nbsp;本人在大学期间就已经尝试过很多种乱七八糟的副业。也得出了一个结论:当今这个社会想饿死自己是一件很难的事情,在大城市靠一些信息差很容易就能赚到钱。所以也没那么怕失业裁员。3.&nbsp;本人是金牛座很爱钱,进互联网可以让我在年轻的适合就享受相对高品质的生活,以及更快的攒到第一桶金。以及,其实在东亚家庭里面,钱代表话语权。4.&nbsp;讨厌体制内的中年领导和热衷打探你私生活没有边界感的同事。当然,以上仅能代表个人的择业观。省会电网本身是个非常非常好的工作,只是不适合和我类似情况的个体。因为在牛客看到了太多劝退互联网无脑进体制内的内容,也想代表非主流的观点发发声。最后,希望所有人都能基于心底真正的想法来进行工作的选择,而非基于对未来不确定性的担忧和恐惧~还没找定工作的朋友们也不要着急,最近有很多补录机会。希望大家都能拿到自己满意的offer!希望大家的2025都能精彩充实! #我的求职思考#&nbsp;&nbsp;#秋招结束# #大厂#&nbsp;&nbsp;#电网#&nbsp;&nbsp;#2025秋招#&nbsp;&nbsp;
Java抽象带篮子:集美你的决定是正确的😍
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务