您的位置:首页 > 其它

最小生成树 ,prim 和Kruskal 算法

2017-05-21 09:45 405 查看
prim 算法 类似于dijstra算法, 个人认为是 dijstra的简化版;    两个算法都是记录从v0- vn 点之间 距离的最短  

找到后 相加就可以

Kruskal  算法  用到 优先队列来 选择权值 由小到大,
 并查集 来 看是不是形成回路(说白了就是 两个点的上级是不是一个人,不是 加进去,是放弃)

Kruskal算法的过程:

(1) 将全部边按照权值由小到大排序。

(2) 按顺序(边权由小到大的顺序)考虑每条边,只要这条边和我们已经选择的边不构成圈,就保留这条边,否则放弃这条边。

算法 成功选择(n-1)条边后,形成一个棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通。

两个 都没有记录路径(没写-  -)

prim 算法: 模板

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stdio.h>

const int inf=1<<29;
using namespace std;

int maps[1010][1010];
int dis[101000];
int n,m,sum;
int vis[10100];

void prim(int v0)
{
int i,j,mid,k;
for(i=1;i<=n;i++)
{
dis[i]=maps[v0][i];
}
memset(vis,0,sizeof(vis));
vis[v0]=true;
for(i=1;i<n;i++)
{
mid=inf;
k=-1;
for(j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<mid)
{
mid=dis[j];
k=j;
}
}
sum+=dis[k];
vis[k]=true;
for(j=1;j<=n;j++)
{
if(!vis[j]&&maps[k][j]<dis[j])
dis[j]=maps[k][j];
}
}

}
int main()
{
cin>>n>>m;
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i==j)
maps[i][i]=0;
else
maps[i][j]=inf;
}
int x,y,z;
for(i=0;i<m;i++)
{
cin>>x>>y>>z;
// if(z<maps[x][y])
maps[x][y]=maps[y][x]=z;
}
sum=0;
prim(1);
cout<<sum<<endl;
return 0;
}


kruskal 算法模板:

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stdio.h>

const int inf=1<<29;
using namespace std;

typedef long long ll;
struct edge{
int f;
int t;
int cost;
friend bool operator < (const edge &x,const edge &y)
{
return x.cost>y.cost;// 优先队列 由小到大排列; >
}
};

int sum;
int boss[10100];
int n,m;
priority_queue <edge> Q;// 优先队列
void table()
{
while(!Q.empty())Q.pop();
for(int i=0;i<1010;i++)
boss[i]=i;
}
int finds(int x)
{
int k=x;
while(boss[k]!=k)
k=boss[k];
return k;
}
void Kruskal()
{

int num=0;
while(!Q.empty()&&num!=n-1)
{
edge u=Q.top();
Q.pop();
int fx=finds(u.f);
int fy=finds(u.t);
if(fx!=fy)// 构不成回路 上级不同
{
boss[fx]=fy;//
4000
合并上级
sum+=u.cost;
num++;
}
}

}
int main()
{
cin>>n>>m;
table();
int i,j,f,t,cost;
for(i=0;i<m;i++)
{
cin>>f>>t>>cost;
edge node;
node.f=f;
node.t=t;
node.cost=cost;
Q.push(node);
}
sum=0;
Kruskal();
cout<<sum<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: