prime算法參考點擊打開鏈接http://blog.csdn.net/yeruby/article/details/38615045
1. prime算法和dijkstra算法的主要區別
Dijkstra算法的對象無所謂是有向圖還是無向圖,它可以求單源最短路徑(一個點到其餘各點的最短路徑),時間複雜度爲O(n*n)。非常相似prime算法,只有一個區別,
核心思想就是更新連接路徑時,prime中是跟蹤接下來的結點到生成樹中的最小交叉邊,而dijkstra中是跟蹤接下來的結點到
起點所有經過的結點的路徑和,這樣說不太好理解,
以下圖舉個例子(只分析v5):初始化後(以v1爲起點),在prime中,v5原本連在v1上(v5路徑長度爲無窮),第一次更新路徑時,v5連在v3上(v5路徑長度爲6),同樣的條件下,在dijkstra中,v5原本連在v1上(v5路徑長度爲無窮)也變爲連在v3上,可是路徑長度變爲7(1+6),這就是兩者的區別了!
2. 代碼實現
#include<iostream>
#include<fstream>
#define max 100
#define infinity 0x7fffffff
using namespace std;
struct MinPath
{
int path;//該邊所對應的起點(存放路徑)
double lowcost;//該邊終點所對應的權值(存放路徑長度)
bool test;//判斷該點是否已找到從起點到它的最短路徑
};
class MGraph
{
public:
MGraph();
double Dijstra(int v);
void dfspath(int i,int v);//回溯起點v到終點i的最短路徑
void PrintPath(int v);//打印起點v到各點的最短路徑
private:
int graph[max][max];
int vexnum,edgenum;double sumcost;//分別爲總結點數,總邊數,最小路徑權值和
MinPath *minpath;
};
MGraph::MGraph():sumcost(0)
{
int i,j,lowcost;
ifstream in("data.txt");
if(!in.fail())
{
in>>vexnum>>edgenum;
for( i=1;i<=vexnum;++i)
{
for(j=1;j<=vexnum;++j)
{
if(i==j)
{
graph[i][j]=0;
}
else
graph[i][j]=infinity;
}
}
for(int k=1;k<=edgenum;++k)//賦值有連接的邊
{
in>>i>>j>>lowcost;
graph[i][j]=graph[j][i]=lowcost;
}
}
in.close();
}
double MGraph::Dijstra(int v)
{
minpath=new MinPath[vexnum+1];
for(int i=1;i<=vexnum;++i)
{
minpath[i].path=v;
minpath[i].lowcost=graph[v][i];
minpath[i].test=false;
}
minpath[v].test=true;
for(int i=2;i<=vexnum;++i)//第一個點已加入,剩下還要加vexnum-1個
{
int minid=0;minpath[minid].lowcost=infinity;
for(int j=1;j<=vexnum;++j)
{
if(!minpath[j].test&&minpath[minid].lowcost>minpath[j].lowcost)
minid=j;
}
cout<<"V"<<v<<"-->V"<<minid<<"="<<minpath[minid].lowcost<<endl;
sumcost+=minpath[minid].lowcost; minpath[minid].test=true;
for(int j=1;j<=vexnum;++j)
{
if(!minpath[j].test&&minpath[minid].lowcost+graph[minid][j]<minpath[j].lowcost)
{
minpath[j].lowcost=minpath[minid].lowcost+graph[minid][j];
minpath[j].path=minid;
}
}
}
return sumcost;
}
void MGraph::dfspath(int i,int v)
{
if(v==i)
return ;
else
{
int j=i;
i=minpath[i].path;//回溯,i是j前面一個數
dfspath(i,v);
if(v==i)
cout<<"V"<<i<<"-->V"<<j;
else
cout<<"-->V"<<j;
}
}
void MGraph::PrintPath(int v)
{
for(int i=1;i<=vexnum;++i)
{
if(i!=v)
{
dfspath(i,v);
cout<<endl;
}
}
}
int main()
{
MGraph mg;int v;
cout<<"請輸入起點序號v";
cin>>v;
cout << "最小權值和="<<mg.Dijstra(v)<<endl;
cout<<"單源最短(完整)路徑:"<<endl;
mg.PrintPath(v);
return 0;
}