7.20 第一场 KD-Graph

KD-Graph

Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2504 Accepted Submission(s): 699

Problem Description

Let’s call a weighted connected undirected graph of n vertices and m edges KD-Graph, if the
following conditions fulfill:

* n vertices are strictly divided into K groups, each group contains at least one vertice

* if vertices p and q ( p ≠ q ) are in the same group, there must be at least one path between p and q meet the max value in this path is less than or equal to D.

* if vertices p and q ( p ≠ q ) are in different groups, there can’t be any path between p and q meet the max value in this path is less than or equal to D.

You are given a weighted connected undirected graph G of n vertices and m edges and an integer K.

Your task is find the minimum non-negative D which can make there is a way to divide the n vertices into K groups makes G satisfy the definition of KD-Graph.Or −1 if there is no such D exist.

Input

The first line contains an integer T (1≤ T ≤5) representing the number of test cases.
For each test case , there are three integers n,m,k(2≤n≤100000,1≤m≤500000,1≤k≤n) in the first line.
Each of the next m lines contains three integers u,v and c (1≤v,u≤n,v≠u,1≤c≤109) meaning that there is an edge between vertices u and v with weight c.

Output

For each test case print a single integer in a new line.

Sample Input

2
3 2 2
1 2 3
2 3 5
3 2 2
1 2 3
2 3 3

Sample Output

3
-1

大概题意

当图以d为分界点,大于d的视为断路,小于d的视为通路,能将图分为k个子图。求d

思路

将每条边按权值排序,通过并查集分为k个子图时,当前边的权值即为所求。

代码

//
// Created by Black on 2021/7/24.
//

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;
const int N = 1000110;
int p[N];

class edge {
public:
    int s, e;
    int v;

    bool operator<(edge &x) {
        return this->v < x.v;
    }
};

edge a[N];

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

void play() {
    int n, k, m;
    scanf("%d%d%d", &n, &m, &k);
    int cur = n;
    for (int i = 0; i <= n; ++i)
        p[i] = i;
    for (int i = 1; i <= m; ++i)
        scanf("%d%d%d", &a[i].s, &a[i].e, &a[i].v);
    sort(a + 1, a + m + 1);
    int d = 0;
    for (int i = 1; i <= m; ++i) {
        if (a[i].v != a[i - 1].v)
            if (cur == k)
                break;
        if (find(a[i].s) == find(a[i].e))
            continue;
        p[find(a[i].s)] = find(a[i].e);
        cur--;
        d = a[i].v;
    }
    printf("%d\n", cur == k ? d : -1);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--)
        play();
    return 0;
}
posted @   嘿,抬头!  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示