题面:已知n个点,m条边,要求对所有点分成k块,D大于等于一块区域最大路径,D小于不在同一区域两点距离的最小值。求D的最小值。
解析:依题知,求D的最小值,K块中的路径尽可能小。
假设开始时n个点构成n块。于是我们可以对边从小到大排序,将小的边的起始点并入终点,进行并查集操作,n--。直至构成构成k块,则当前阶段的边为D。否则输出‘-1’。
代码

#include<bits/stdc++.h>
using namespace std;
int t,n,m,k;
struct node{
    int s,e,w;
}s[500005];
int fa[500005];
int find(int x){
    if(fa[x]==x) return x;
    fa[x]=find(fa[x]);
    return fa[x];
}
bool cmp(node a,node b){
    return a.w<b.w;
}
void solve(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++)
    scanf("%d%d%d",&s[i].s,&s[i].e,&s[i].w);
    sort(s+1,s+m+1,cmp);
    int ans=0,now=n;
    for(int i=1;i<=m;i++){
    if(s[i].w!=s[i-1].w&&now==k) {
        printf("%d\n",ans);
        return ;
    }
    if(find(s[i].s )==find(s[i].e )) continue;    
    now--;
    fa[find(s[i].s )]=find(s[i].e);
    ans=s[i].w;
    }    
    printf("%d\n",k==now?ans:-1);
}
int main(){
    cin>>t;
    while(t--)
    solve();

}