您的位置:首页 > 其它

最小生成树(Prim算法及优化)

2019-05-05 20:46 204 查看

Prim算法和Dijkstra算法很像教科书的复杂度是O(V^2),同Dijkstra算法的复杂度。在Dijkstra算法中,可以用优先队列来优化,同样,也可以用优先队列来优化Prim算法,使它的复杂度变成Elong(E)。但是还不如用Kruskal算法,实现起来更加简单。
ElogE算法

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define maxn 1005
using namespace std;

int visited[maxn] = {0};

struct node{
int value;
int num;
};

struct graph{
vector<node> edge;
}g[maxn];

int main()
{
priority_queue<node> q;
int n,m,ans = 0;
cin >> n >> m;
vector<int> lowercost(n+1,(1<<30));
for( int i = 0 ; i < m ; i++ )
{
int x,y,v;
cin >> x >> y >> v;
node t;
t.value = v;
t.num = y;
g[x].edge.push_back(t);
t.num = x;
g[y].edge.push_back(t);
}
int begin = 1,minx = 0;   //从begin这个点来开始生成最小生成树
lowercost[begin] = 0;
for( int i = 0 ; i < n-1 ; i++ )    //遍历n-1次生成最小生成树
{
for(int j = 0 ; j < g[begin].edge.size() ; j++ )      //遍历该点相邻的所有边更新权值
{
visited[begin] = 1;
int t = g[begin].edge[j].num;
if( lowercost[t] > g[begin].edge[j].value )
{
lowercost[t] = g[begin].edge[j].value;
q.push(g[begin].edge[j]);
}
}
while( visited[q.top().num] )
{
q.pop();
}
begin = q.top().num;
ans += lowercost[begin];
q.pop();
}
cout << ans << endl;
return 0;
}

O(V^2)的算法
在边是V^2这个量级的时候,用这种代码会比Kruskal算法快

#include <iostream>
#include <vector>
#include <algorithm>
#define maxn 1005
using namespace std;

int visited[maxn] = {0};

struct node{
int value;
int num;
bool operator<(const node&n) const
{
return value > n.value;
}
};

struct graph{
vector<node> edge;
}g[maxn];

int main()
{
int n,m,ans = 0;
cin >> n >> m;
vector<int> lowercost(n+1,(1<<30));
for( int i = 0 ; i < m ; i++ )
{
int x,y,v;
cin >> x >> y >> v;
node t;
t.value = v;
t.num = y;
g[x].edge.push_back(t);
t.num = x;
g[y].edge.push_back(t);
}
int begin = 1,minx = 0;   //从begin这个点来开始生成最小生成树
lowercost[begin] = 0;
for( int i = 0 ; i < n-1 ; i++ )    //遍历n-1次生成最小生成树
{
for(int j = 0 ; j < g[begin].edge.size() ; j++ )      //遍历该点相邻的所有边更新权值
{
visited[begin] = 1;
int t = g[begin].edge[j].num;
if( lowercost[t] > g[begin].edge[j].value )
{
lowercost[t] = g[begin].edge[j].value;
}
}
minx = 1<<30;
for( int j = 0 ; j < n ; j++ )      //找最小花费时直接遍历这个lowercost数组
{
if( !visited[i] && minx > lowercost[j] )
{
minx = lowercost[j];
begin = j;
}
}
}
cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: