说明
小明所在的城镇有m条路连接了n个区(n个区的编号在1~n的范围内),每条大道将两个区相连接,每条大道有一个拥挤度。小明想要开车从s区去t区,请你帮他规划一条路线,使得经过道路的拥挤度的最大值最小。
输入格式
第一行有四个用空格隔开的n,m,s,t,其含义见题目描述。
接下来m行,每行三个整数u,v,w,表示有一条大道连接区u和区v,且拥挤度为w。
两个区之间可能存在多条大道。
数据规模与约定
对于 30% 的数据,保证n≤10。
对于 60% 的数据,保证n≤100。
对于 100% 的数据,保证1≤n≤10^4,1≤m≤2×10^4, w≤10^4,1≤s,t≤n。且从 s 出发一定能到达 t 区。
输出格式
输出一行一个整数,代表最大的拥挤度。
样例
输入数据 1
3 3 1 3
1 2 2
2 3 1
1 3 3
Copy
输出数据 1
2
反思总结:
这是一道最小生成树的模板变换题
题目意思:
求从一个区域到另一个区域的过程中拥挤度的最大值。
我们可以根据克鲁斯卡尔(Kruskal)最小生成树算法,生成一条包含 s 区域和 t 区域的最小生成树。
因为克鲁斯卡尔算法,是将边从小到大加入,所以,我们只需要在把 t 区域加进来之前不断地更新拥挤度的最大值,直到把 t 区域加进来即可。
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define ll long long
int n,m,s,t;
struct node {
int u;
int v;
int w;
};
node a[20007];
int fa[20007];
bool cmp(node aa,node bb) {
return aa.w<bb.w;
}
void init() {
for(int i=1; i<=n; i++) {
fa[i]=i;
}
}
int find(int x) {
while(x!=fa[x])
x=fa[x];
return x;
}
int ans=0;
void kriscal() {
int sum=0;
int cnt=n;
for(int i=1; i<=m; i++) {
int u=a[i].u;
int v=a[i].v;
int w=a[i].w;
u=find(u);
v=find(v);
if(u!=v) {
fa[v]=u;
}
ans=max(a[i].w,ans);
if(find(s)==find(t))
return;
}
}
int main() {
cin>>n>>m>>s>>t;
init();
for(int i=1; i<=m; i++) {
cin>>a[i].u>>a[i].v>>a[i].w;
}
sort(a+1,a+m+1,cmp);
kriscal();
cout<<ans<<endl;
return 0;
}