题目链接
对于N个点M条边,要求满足题目上述条件的D的最小值。
二分D,显然D如果很大是可以满足条件的,有个临界值。check的时候并查集就行了,check是否当前有K个集合。
int n, m, k;
int vis[maxn];
struct node
{
int u, v, w;
} a[maxn], b[maxn];
bool cmp(node A, node B)
{
return A.w < B.w;
}
int fa[maxn];
int find1(int x)
{
return fa[x] == x ? x : fa[x] = find1(fa[x]);
}
int sum;
int zu;
int chekc(int d)
{
for (int i = 1; i <= n; i++)
fa[i] = i;
// cout << sum <<"ssad" <<endl;
for (int i = 1; i <= m;i++)
{
int x = find1(a[i].u);
int y = find1(a[i].v);
if(x==y)
continue;
if(a[i].w<=d)
fa[x] = y;
}
// cout<<ans<<" "<<x<<endl;
for (int i = 1; i <= n; i++)
if(fa[i]==i)
zu++;
//printf("%d\n",zu);
return zu<=k;
}
int main()
{
IOS;
int T;
cin >> T;
while (T--)
{
sum = 0;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
{
fa[i] = i;
}
for (int i = 1; i <= m; i++)
{
cin >> a[i].u >> a[i].v >> a[i].w;
}
sort(a + 1, a + 1 + m, cmp);
int ans = -1;
int l = 0, r = 1e9 + 7;
while (r >= l)
{
int mid = (l + r) >> 1;
zu=0;
if (chekc(mid))
{
r = mid - 1;
if(zu==k)
ans = mid;
}
else
{
l = mid + 1;
}
}
cout << ans << endl;
}
return 0;
}