static boolean[] mark;//是否访问过该顶点
static Queue<int[]> pq;//存储横切边权重及另一个顶点
static Deque<Edge>[] adj;//无向加权图
static int ans=0;
static class Edge {
private final int v;//两个顶点
private final int w;
private final int weight;//权重
public Edge(int v,int w,int weight){
this.v=v;
this.w=w;
this.weight=weight;
}
//获取权重
public int weight(){
return weight;
}
//获取某个顶点
public int either(){
return v;
}
//获取另一个顶点
public int other(int vertex){
if(vertex==v)
return w;
else return v;
}
}
public static int minCostConnectPoints(int[][] points) {
int n=points.length;
adj=new ArrayDeque[n];
mark=new boolean[n];
pq=new PriorityQueue<>((o1, o2) -> o1[0]-o2[0]) ;
//建立无向加权图
for (int i = 0; i < n; i++) {
for (int j = i+1; j <n ; j++) {
if(adj[i]==null)
adj[i]=new ArrayDeque<>();
adj[i].offer(new Edge(i,j,Math.abs(points[i][0]-points[j][0])
+Math.abs(points[i][1]-points[j][1])));
if(adj[j]==null)
adj[j]=new ArrayDeque<>();
adj[j].offer(new Edge(i,j,Math.abs(points[i][0]-points[j][0])
+Math.abs(points[i][1]-points[j][1])));
}
}
pq.offer(new int[]{0,0});//从0点开始
//当所有顶点加入后没有横切边
while (!pq.isEmpty()){
int[] tmp=pq.poll();//最小权重边
int to=tmp[1];
int weight=tmp[0];
//判断是否为横切边,不是则跳过
if(!mark[to]){
ans+=weight;
visit(adj,to);
}
}
return ans;
}
public static void visit(Deque<Edge>[] adj, int v){
mark[v]=true;
//枚举顶点的所有边
for (Edge e :adj[v]) {
int w=e.other(v);//另一个顶点
if(!mark[w]){
//添加到队列中排序
pq.offer(new int[]{e.weight(),w});
}
}
}
最小生成树prim算法leetcode.1584
最新推荐文章于 2023-09-16 22:13:25 发布