题意:将无向图的顶点分为
k
k
k个集合,满足:
1.
1.
1.不同集合任意两点路径中最大值大于
D
D
D
(
(
(边权小于等于
D
D
D的两点一定在同一集合里
)
)
)
2.
2.
2.同一集合任意两点,至少存在一条路径中最大值小于等于
D
D
D
(
(
(这两点除去路径值大于
D
D
D的,任然是连通的,根据
1
1
1,即为同一集合
)
)
)
题目即求:边权为
w
[
i
]
w[i]
w[i],当
w
[
i
]
w[i]
w[i]
<
=
<=
<=
D
D
D时,就认为这两点在同一集合中,求最小的
D
D
D,使顶点恰好被分为
k
k
k个集合。
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define ll long long
int f[100005];
struct edge{
int a,b;
int val;
}e[500005];
bool cmp(edge p,edge q){
return p.val<q.val;
}
int find(int x){
if(x==f[x]) return f[x];
else return f[x]=find(f[x]);
}
signed main()
{
int T; cin>>T;
while(T--){
int n,m,k; cin>>n>>m>>k;
for(int i=1;i<=m;i++) cin>>e[i].a>>e[i].b>>e[i].val;
if(k==n) cout<<0<<endl;
else{
for(int i=1;i<=n;i++) f[i]=i;
sort(e+1,e+1+m,cmp);
int cnt=n,ans=-1;
for(int i=1;i<=m;i++){
int V=e[i].val;
for(;e[i].val==V&&i<=m;i++){
int u=find(e[i].a),v=find(e[i].b);
if(u!=v){
f[u]=find(v);
cnt--;
}
}
if(cnt==k){
ans=V;
break;
}
else if(cnt<k) break;
}
cout<<ans<<endl;
}
}
}