如题,二者的区别是:
最小生成树是计算从一节点到另一节点的最小边集;最短路是带权路径,计算权值最小。
即最小生成树要经过每一个点,而最短路只需要能从起点到达终点,使得两点路径权值最小即可。
常用
【最短路】常用的算法有dijkstra,bellman-ford,floyd,而【最小生成树】则是prim和kruskal。
下面是各个算法的模板
最小生成树:
prime,复杂度0(n^2),适用于稠密图
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 30;
int n; //节点数
int mp[N][N];//地图
int dis[N];//存储距离
int vis[N];//标记
int prime(int s) //传进起始点
{
int sum = 0; //权值总和
for(int i = 0;i < n;i ++) //初始化起始点到各点的距离
dis[i] = mp[s][i];
vis[s] = 1;
for(int i = 1;i <= n - 1;i ++)
{
// n - 1次迭代
int minn = inf;
int p;
for(int j = 0;j < n;j ++) //找到距离最小的点
{
if(!vis[j] && dis[j] < minn)
minn = dis[j], p = j;
}
vis[p] = 1;
sum += minn; //加上边权值
for(int j = 0;j < n;j ++) //松弛操作
{
if(!vis[j] && dis[j] > mp[p][j])
dis[j] = mp[p][j];
}
}
return sum;
}
Kruskal, 复杂度O(e * loge), 适用于稀疏边
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 30;
const int M = 100;
struct edge{
int a, b;
int v;
};
edge e[M];
int fa[N];
int n, m; //n是点数,m是边数
void init()
{
for(int i = 0;i <= n;i ++)
fa[i] = i;
}
bool cmp(edge a,edge b)
{
return a.v < b.v;
}
int Find(int x)
{
if(x != fa[x])
fa[x] = Find(fa[x]);
return fa[x];
}
int Merge(int x,int y)
{
int fx = Find(x);
int fy = Find(y);
if(fx != fy)
{
fa[fx] = fy;
return 1;
}
return 0;
}
int Kruksal()
{
//加边
for(int i = 0;i < m;i ++)
{
cin >> e[i].a >> e[i].b >> e[i].v;
}
//按权值排序
sort(e, e + m, cmp);
//总消耗
int sum = 0;
for(int i = 0;i < m;i ++)
{
if(Merge(e[i].a, e[i].b))
sum += e[i].c;
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
return 0;
}