口袋的天空(Kruscal)

1.9k 词

题目描述

小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。

有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。

给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起。

现在小杉要把一些云朵连在一起,做成K个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。

输入

每组测试数据的 第一行有三个数N,M,K(1<=N<=1000,1<=M<=10000,1<=K<=10) 接下来M个数每行三个数X,Y,L,表示X云和Y云可以通过L的代价连在一起。(1<=X,Y<=N,0<=L<10000) 30%的数据N<=100,M<=1000

输出

对每组数据输出一行,仅有一个整数,表示最小的代价。 如果怎么连都连不出K个棉花糖,请输出’No Answer’。

样例输入

1
2
3 1 2
1 2 1

样例输出

1
1

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import java.util.Arrays;
import java.util.Scanner;
public class Main{
static Scanner sc=new Scanner(System.in);
static class Node implements Comparable<Node>{
int x,y,l;
Node(int x,int y,int l){
this.x=x;
this.y=y;
this.l=l;
}
@Override
public int compareTo(Node o) {
return this.l-o.l;
}
}
public static void main(String[] args) {
while(sc.hasNext()){
int n=sc.nextInt(),
m=sc.nextInt(),
k=sc.nextInt();
Node[] node=new Node[m];
for(int i=0;i<m;i++){
node[i]=new Node(sc.nextInt(),
sc.nextInt(),
sc.nextInt());
}
if(k>n){
System.out.println("No Answer");
continue;
}
if(k==n){
System.out.println("0");
continue;
}
Arrays.sort(node);
if(!Kruscal(node,n,m,k))
System.out.println("No Answer");
}
sc.close();
}
static int count,cost;
private static boolean Kruscal(Node[] node, int n, int m,int k) {
int[] flag=new int[n+1];
for(int i=1;i<=n;i++)
flag[i]=i;
count=n;cost=0;
for(int i=0;i<m;i++){
merge(node[i].x,node[i].y,node[i].l,flag);
if(count==k) {
System.out.println(cost);
return true;
}
}
return false;
}
private static int find(int[] flag,int a){
if(a!=flag[a])
flag[a]=find(flag,flag[a]);
return flag[a];
}
private static void merge(int a,int b,int c,int[] flag){
int fa=find(flag,a);
int fb=find(flag,b);
if(fa!=fb){
flag[fa]=fb;
count--;
cost+=c;
}
}
}