P1396 营救

题目分析:

  1. 并查集+二分法
  2. 答案区间[l,r] (l 为 边的最小值,r 为 边的最大值)

代码如下:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>

using namespace std;

#define inf 0x3f3f3f3f
#define eps 1e-6
#define db double
#define ll long long
#define  mm(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pb push_back
#define el endl
#define debug(x) cerr<<#x<<" = "<<x<<endl
#define fgx cerr<<"-------------------------"<<endl
#define shutio ios::sync_with_stdio(false),cin.tie(0)
#define  mk make_pair
#define lowbit(x) (x) & (-x)
#define fi first
#define se second

const int N = 2e4 + 10;

int n,m,s,t;
pii node[N];
int w[N];
int fa[N];
int l,r;

void init(){
    for(int i = 1; i <= n; i ++ ){
        fa[i] = i;
    }
}

int find(int x){
    if(fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}

void merge(int a,int b){
    fa[find(a)] = find(b);    
}

bool check(int x){
    init();
    for(int i = 0; i < m; i ++ ){
        if(w[i] > x) continue;
        merge(node[i].fi,node[i].se);
    }
    if(find(s) == find(t)) return true;
    else return false;
}

int main() {
    shutio;
    cin >> n >> m >> s >> t;
    l = inf,r = -inf;
    for(int i = 0; i < m; i ++ ){
        int a,b,c; cin >> a >> b >> c;
        node[i] = {a,b};w[i] = c;
        l = min(l,w[i]),r = max(r,w[i]);
    }
    while(l < r){
        int mid = (l + r) >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    cout<<l;    
    return 0;
}