代码随想录算法训练营打卡第57天:prim算法,kruskal算法

prim算法

题目链接:53. 寻宝(第七期模拟笔试)

文章链接:代码随想录

prim算法的目的就是找到最小生成树

prim算法核心就是三步,我称为prim三部曲,大家一定要熟悉这三步,代码相对会好些很多:

第一步,选距离生成树最近节点。第二步,最近节点加入生成树。第三步,更新非生成树节点到生成树的距离(即更新minDist数组)

具体实现代码如下:

import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int v=sc.nextInt();
int e=sc.nextInt();

int[][] grid=new int[v+1][v+1];

for(int i=0;i<v+1;i++){
Arrays.fill(grid[i],10000);
}


for(int i=0;i<e;i++){
int x=sc.nextInt();
int y=sc.nextInt();
int r=sc.nextInt();
grid[x][y]=r;
grid[y][x]=r;
}

boolean[] b=new boolean[v+1];

int[] minDist=new int[v+1];
Arrays.fill(minDist,10000);

for(int i=0;i<v;i++){
int cur=-1;
int maxvalue=Integer.MAX_VALUE;

for(int j=1;j<=v;j++){
if(!b[j]&&minDist[j]<maxvalue){
cur=j;
maxvalue=minDist[j];
}
}
b[cur]=true;


for(int j=1;j<=v;j++){
if(!b[j]&&grid[cur][j]<minDist[j]){
minDist[j]=grid[cur][j];
}
}
}

int result=0;
for(int i=2;i<v+1;i++){
result+=minDist[i];
}
System.out.println(result);
}
}

kruskal算法

与刚才的题目是一样的只不过换了一种方法去解决,使用了并查集,首先先用并查集的模板初始化一个并查集,同时创建一个边的对象,接着将输入的值进行赋值,然后用自定义规则对边对象进行排序

 edges.sort(Comparator.comparingInt(edge -> edge.val));

接着就是使用并查集的特性从小到大判断边是不是在一个集合里,最后输出最小值,具体代码如下:

import java.util.*;
 class Edge{
int l,r,val;

Edge(int l,int r,int val){
this.l=l;
this.r=r;
this.val=val;
}
}

public class Main{

public static int n=10000;
public static int[] father=new int[n];
public static void init(){
for(int i=0;i<n;i++){
father[i]=i;
}
}

public static int find(int u){

return father[u]==u?u:(father[u]=find(father[u]));

}

public static void join(int u,int v){
u=find(u);
v=find(v);
if(v==u) return;
father[v]=u;
}

public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int u=sc.nextInt();
int v=sc.nextInt();
List<Edge> list=new ArrayList<>();
for(int i=0;i<v;i++){
int l=sc.nextInt();
int r=sc.nextInt();
int val=sc.nextInt();
list.add(new Edge(l,r,val));
}

list.sort(Comparator.comparingInt(edge -> edge.val));
 
init();

int result=0;
for(Edge e:list){
int x=find(e.l);
int y=find(e.r);
if(x!=y){
result+=e.val;
join(x,y);
}
}

System.out.println(result);

}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值