区别:
最小生成树能够保证整个图所有路径和最小,但不能保证任意两点间是最短路径。最短路径是从一点出发,到达目的地路径最短。
实现方法:
最通用:普里姆算法
先把给定定点加入集合,然后将集合内的顶点与集合外的顶点所构成的所有边中选取权值最短的一条,并将集合外的顶点加入集合中,表示该顶点已连通。不断循环。
它是一种与Dijkstra十分类似的算法,只不过每次找最短边是在已经加入点的集合中找,而不是在新加入的点周围扩展。
JungleRoad
模板题,附代码
#include<stdio.h>
#include<string.h>
#include <iostream>
using namespace std;
#define inf 0xffffff
int map[30][30],n,dist[30];
bool vis[30];
int prim(){
int i,j,mi,v;
for(i=0;i<n;i++)
{
dist[i]=map[0][i];
vis[i]=0;
}
for(i=1;i<=n;i++)
{
mi=inf;
for(j=0;j<n;j++)
{
if(!vis[j] && mi>dist[j])
{
v=j;
mi=dist[j];
}
}
vis[v]=1;
for(j=0;j<n;j++)
if(!vis[j] && dist[j]>map[v][j])
dist[j]=map[v][j];
}
for(i=1;i<n;i++) dist[0]+=dist[i];
return dist[0];
}
int main(){
int i,j,m,c;
char a[2],b[2];
while(scanf("%d",&n) && n)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
for(i=1;i<n;i++)
{
scanf("%s%d ",&a,&m);
for(j=0;j<m;j++)
{
scanf("%s%d ",&b,&c);
map[a[0]-'A'][b[0]-'A']=map[b[0]-'A'][a[0]-'A']=c;
}
}
cout<<prim()<<endl;
}
return 0;
}