(看到楼下几位同学也有类似的问题,在这里把问题说的稍微详细一点,期待大佬的解答)
定义数组satellite表示该点有没有“增配卫星电话”,建好最小生成树后从大到小查边,将该边的两个端点设为“已增配卫星电话”,“卫星电话”不够时就输出当前边。
下面是删点部分的代码:
for(int i=p-2;i>=0;i--){
int u = tree[i].u;
int v = tree[i].v;
if(satellite[u]==0){
satellite[u]=1;
s--;
}
if(satellite[v]==0){
satellite[v]=1;
s--;
}
if(s<0){ System.out.printf("%.2f",tree[i].w);
break;
}
}
后来看了题解的做法,最后(s-1)条边舍弃,直接输出(tree[p-s-1].w),这样就过了。。
萌新想不明白这两种有什么区别,向大佬们求助。
import java.io.*;
import java.util.*;
public class Main{
static class Edge{
int u,v;
double w;
Edge(int u,int v,double w){
this.u = u;
this.v = v;
this.w = w;
}
}
static Edge[] edge = new Edge[130000];
static int[] a = new int[510];
static int[] satellite = new int[510];
static int find(int x){
if(x!=a[x]){
a[x] = find(a[x]);
}
return a[x];
}
static void unity(int x,int y){
int r1 = find(x);
int r2 = find(y);
a[r1] = r2;
}
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
Read in = new Read(System.in);
for(int i=0;i<510;i++)a[i] = i;
int s = in.nextInt();
int p = in.nextInt();
int[] x = new int[510];
int[] y = new int[510];
for(int i=1;i<=p;i++){
x[i] = in.nextInt();
y[i] = in.nextInt();
}
int cnt = 0;
for(int i=1;i<=p;i++){
for(int j=i+1;j<=p;j++){
edge[cnt++] = new Edge(i,j,Math.sqrt(Math.pow(x[i]-x[j],2)+Math.pow(y[i]-y[j],2)));
}
}
Arrays.sort(edge,0,cnt, new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return Double.compare(o1.w, o2.w);
}
});
// for(int i=0;i<cnt;i++){
// System.out.println(edge[i].u+" "+edge[i].v+" "+edge[i].w);
// }
Edge[] tree = new Edge[p-1];
int flag=0;
for(int i=0;i<cnt;i++){
int u = edge[i].u;
int v = edge[i].v;
if(find(u)!=find(v)){
unity(u,v);
tree[flag++] = new Edge(u,v,edge[i].w);
}
}
//直接输出第p-s-1条边
System.out.printf("%.2f",tree[p-s-1].w);
//下面是删点的做法
// for(int i=p-2;i>=0;i--){
// int u = tree[i].u;
// int v = tree[i].v;
// if(satellite[u]==0){
// satellite[u]=1;
// s--;
// }
// if(satellite[v]==0){
// satellite[v]=1;
// s--;
// }
// if(s<0){
// System.out.printf("%.2f",tree[i].w);
// break;
// }
// }
}
}
class Read {//自定义快读 Read
public BufferedReader reader;
public StringTokenizer tokenizer;
public Read(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine() {
String str = null;
try {
str = reader.readLine();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return str;
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public Double nextDouble() {
return Double.parseDouble(next());
}
// public BigInteger nextBigInteger() {
// return new BigInteger(next());
// }
}