P1991 无线通讯网 java实现
作者:互联网
题目链接:P1991 无线通讯网
这是一道最小生成树的题目.在计算出最小生成树后,将使用卫星电话的最大值去除即可.
小优化:
在并查集中,为了find的节点层级尽可能少,在union的时候将低层级的树并入高层级,这样能够减少树的高度.
所以代码里使用level记录find时候的高度,在union的时候,根据这个判断来进行union.
以下是代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static int[] pointIdx;
static Point[] points;
static BufferedReader br;
static StringTokenizer st;
static PriorityQueue
static PriorityQueue
static boolean[][] hasAdd;
static int[] level;
public static void main(String[] args) throws Exception {
br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
int S = Integer.parseInt(st.nextToken());
int P = Integer.parseInt(st.nextToken());
init(P);
points = new Point[P+1];
int px;
int py;
for(int i = 1;i<=P;i++){
st = new StringTokenizer(br.readLine());
px = Integer.parseInt(st.nextToken());
py = Integer.parseInt(st.nextToken());
points[i] = new Point(px,py);
}
pq = new PriorityQueue<>(new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return Double.compare(o1.dist,o2.dist);
}
});
hasAdd = new boolean[points.length][points.length];
for(int i = 1;i<points.length;i++){
for(int j = 1;j<points.length;j++){
if(i == j){
continue;
}
if(hasAdd[i][j]){
continue;
}
hasAdd[i][j] = hasAdd[j][i] = true;
pq.add(new Edge(i,j,getDist(points[i],points[j])));
}
}
ans = new PriorityQueue<>(new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return Double.compare(o2.dist,o1.dist);
}
});
Edge pollEdge;
while(!pq.isEmpty()){
if(ans.size()==P-1){
break;
}
pollEdge = pq.poll();
if(!connect(pollEdge.start,pollEdge.end)){
union(pollEdge.start,pollEdge.end);
ans.add(pollEdge);
}
}
for(int i =1;i<S;i++){
ans.poll();
}
double ansDist = Math.sqrt(ans.peek().dist);
System.out.printf("%.2f",ansDist);
}
private static double getDist(Point x,Point y){
return Math.pow(x.x-y.x,2)+Math.pow(x.y-y.y,2);
}
static class Edge{
int start;
int end;
double dist;
public Edge(int start, int end, double dist) {
this.start = start;
this.end = end;
this.dist = dist;
}
}
static class Point{
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
private static void init(int N){
pointIdx = new int[N+1];
level = new int[N+1];
for(int i = 0;i<=N;i++){
pointIdx[i] = i;
}
}
private static int find(int a){
if(pointIdx[a] == a){
return pointIdx[a];
}
level[a]++;
return pointIdx[a] = find(pointIdx[a]);
}
private static void union(int a,int b){
level[a]=0;
level[b]=0;
int A = find(a);
int B = find(b);
if(A!=B){
if(level[a]>level[B]){
pointIdx[B] = A;
}
else{
pointIdx[A]=B;
}
}
}
private static boolean connect(int a,int b){
return find(a) == find(b);
}
}
标签:java,int,pollEdge,st,P1991,static,new,无线通讯 来源: https://www.cnblogs.com/reclusiveone/p/14722675.html