P1396 营救

P1396 营救

题目背景

“咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动得热泪盈眶,开起了门……

题目描述

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

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

输入格式

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

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

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

输出格式

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

输入输出样例 #1

输入 #1

3 3 1 3
1 2 2
2 3 1
1 3 3

输出 #1

2

说明/提示

数据规模与约定

  • 对于 \(30\%\) 的数据,保证 \(n\leq 10\)
  • 对于 \(60\%\) 的数据,保证 \(n\leq 100\)
  • 对于 \(100\%\) 的数据,保证 \(1 \leq n\leq 10^4\)\(1 \leq m \leq 2 \times 10^4\)\(w \leq 10^4\)\(1 \leq s, t \leq n\)。且从 \(s\) 出发一定能到达 \(t\) 区。

样例输入输出 1 解释

小明的妈妈要从 \(1\) 号点去 \(3\) 号点,最优路线为 \(1\)->\(2\)->\(3\)
这道题与普通的求最短路不同,这道题要求路中的的最大值的最小值,我原本还想用树形dp但看了题解才明白,这道题要用kruskal算法,当第一个能够使s和t连通的边肯定是答案因为,边是从小到大排序的

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int N=1e4+5;
const int M=1e5+5;
int n,m,s,t,u,v,w;
int d[N];
struct node{
    int x,y,z;
}edge[M];
bool cmp(node e1,node e2){
    return e1.z<e2.z;
}
int f[N];
int find(int x){
    return x==f[x]?x:f[x]=find(f[x]);
}
void kruskal(){
    int ans;
    for(int i=1;i<=n;i++)f[i]=i;
    for(int i=1;i<=m;i++){
        int rootx=find(edge[i].x);
        int rooty=find(edge[i].y);
        if(rootx!=rooty)f[rootx]=rooty;
        find(s),find(t);
        if(f[s]==f[t]){
            ans=edge[i].z;
            break;
        }
    }
    cout<<ans;
}
int main(){
    cin>>n>>m>>s>>t;
    for(int i=1;i<=m;i++){
        cin>>edge[i].x>>edge[i].y>>edge[i].z;
    }
    sort(edge +1,edge+1+m,cmp);
    kruskal();
    return 0;
}
posted @ 2025-03-09 21:08  郭轩均  阅读(46)  评论(0)    收藏  举报