最小生成树两种方法实现

简介: 最小生成树两种方法实现

在数据结构中我们知道最小生成树有两种实现方法,这两种方法一定要熟练,其中prim方法开了两个辅助数组vis[]和dis[];kruskal方法采用了并查集并可以和优先队列(也可以直接用sort排序)结合起来,下面是个人两种方法在邻接表中的实现代码:


#include<iostream> 
#include<vector>
#include<queue> 
using namespace std;
const int maxv=1000;
const int maxe=1000;
const int inf=100000000; 
int n,e;// 结点数,边数 
struct node{
  int vex,weight;
};
vector<node>Adj[maxv];//定义邻接表 
//prim算法部分 
bool vis[maxv];//区别访问和未访问的集合
int dis[maxv];//更新各结点到集合最短距离 
int  prim() {//返回最小生成树之和 
for(int i=0;i<n;i++){ //初始化 
  vis[i]=false;
  dis[i]=inf;
} 
vis[0]=true; //v0点入集合
int k=0,min;//标记当前入集合结点
int sum=0;//记录最小路径和
for(int j=1;j<n;j++) { //剩余n-1个结点
  min=inf;
  for(int i=0;i<Adj[k].size();i++){ //更新dis 
     int v=Adj[k][i].vex;
    if(Adj[k][i].weight<dis[v])
    dis[v]=Adj[k][i].weight;
  }
  for(int i=0;i<n;i++) {
    if(!vis[i]&&dis[i]<min)
    {
      k=i;
      min=dis[i];
    }
  }
  if(min==inf)return -1;//图不连通 
  sum+=min; 
  vis[k]=true;
}
return sum;
} 
//kruskal算法部分
int father[maxe];//并查集
struct edge{
  int x,y;//边两顶点
  int weight;//边权 
  edge(int a,int b,int c){
    x=a;
    y=b;
    weight=c;
  }
  edge(){
  }
}Edge[maxe]; 
struct cmp{
  bool operator ()( int a,int b){
    return Edge[a].weight>Edge[b].weight; 
  }
};
priority_queue<int,vector<int>,cmp>q;//优先队列存放最小边权下标
int  kruskal() {
  int sum=0;//记录最小路径和
  for(int i=0;i<e;i++)
  {father[i]=i;//并查集初始化 
   q.push(i) ;//优先队列存放边 
  } 
    int temp=q.top();q.pop();  //先选出第一条边 
  sum+=Edge[temp].weight;
  int k=Edge[temp].x;   //标记该集合 
  father[Edge[temp].y] =k;
  for(int i=2;i<n;i++) {//选剩下n-2条边  
while(father[Edge[temp].x]==father[Edge[temp].y]&&!q.empty()) 
    {
      temp=q.top();q.pop(); //选出非闭环的边 
    }
    if(father[Edge[temp].x]==father[Edge[temp].y])//先不出边
    return -1; 
    sum+=Edge[temp].weight;
    //标记该集合 
  father[Edge[temp].y] =father[Edge[temp].x]=k;
  //并入集合 ,路径压缩    
  }
  return sum; 
} 
int main(){
  scanf("%d%d",&n,&e);
  int x,y,w;
  node temp;
  for(int i=0;i<e;i++) //初始化邻接表和边表 
  {
    scanf("%d%d%d",&x,&y,&w);
    temp.vex=y;temp.weight=w;
    Adj[x].push_back(temp);
    edge k(x,y,w);
    Edge[i]=k;
  }
  printf("%d\n",prim()) ;
  printf("%d\n",kruskal()) ;
  return 0;
}

这个部分应该多刷题以熟练应用,算是一个重点。

相关文章
|
7月前
|
算法
最小生成树算法:Prim算法
在图论中,最小生成树(Minimum Spanning Tree,简称MST)是一种常用的算法问题。最小生成树是指在一个加权连通图中选取边的子集,使得所有顶点都被覆盖,并且边的总权值最小。
160 0
|
2天前
|
算法
最小生成树算法
最小生成树算法
|
9月前
|
存储 算法 C++
最小生成树问题及Kruskal算法的解析
最小生成树问题及Kruskal算法的解析
73 2
|
算法 C语言
最小生成树——Prim算法与Kruskal算法
最小生成树——Prim算法与Kruskal算法
306 0
最小生成树——Prim算法与Kruskal算法
|
算法
Prim算法(普利姆)最小生成树
Prim算法(普利姆)最小生成树
90 0
|
机器学习/深度学习 算法
无向图的算法:Kruskal算法与Prim算法生成最小生成树
无向图的算法:Kruskal算法与Prim算法生成最小生成树
152 0
|
算法
Prim算法(最小生成树)
Prim算法(最小生成树)
91 0
Prim算法(最小生成树)
|
算法
最小生成树
《基础犀利》
72 0
最小生成树