1.最小生成树与最短路的区别
最小生成树:包含所有的顶点,并且要保证路径之和最小。
最短路:从一点出发,到达目的地顶点的路径最小,即求两点的最短路。
2.最小生成树算法
2.1Prim
每次寻找离当前集合最小的边
例题HDU-1863 通畅工程
模板
。
int prim()
{
int sum = 0; //权值总和
int i,j,k,min;
for(i=1; i<=n; i++)//初始化第一个点到各点的距离,也阔以制定任一点到其余点距离
low[i]=g[1][i];
p = 0;
for(i=1; i<=n; i++)
{
min=inf;
for(j=2; j<=n; j++)//找到距离最小的点
{
if(low[j] != 0&&low[j]<min)
{
min=low[j];
k=j;
}
}
p += 1;
if(min == inf)
break;
low[k] = 0;
sum += min; //加上边权值
for(j=2; j<=n; j++)
{
if(low[j] > g[k][j])
low[j] = g[k][j];
}
}
return sum;
}
2.2 Krustal
按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路。
3.最短路算法
3.1Dijkstra
求带权有向图某个顶点到其余各顶点的最短路径时
例题HDU-1874畅通工程续
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
const int inf = 999999999;
using namespace std;
int low[1010], mst[1010];
int g[1010][1010],n, m, a, b, d, s, t;
void Dijkstra()
{
int i, j, min, k;
for(i = 0; i < n; i++)
{
low[i] = g[s][i];
}
mst[s] = 1;
for(i = 0; i < n; i++)
{
min=inf;
for(j = 0; j < n; j++)
{
if(mst[j]==0&&low[j] < min)
{
min = low[j];
k = j;
}
}
if(min == inf)
break;
mst[k] = 1;
for(j = 0; j < n; j++)
{
if(low[j] > g[k][j] + low[k])
low[j] = g[k][j] + low[k];
}
}
}
int main()
{
int i, j;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(mst, 0, sizeof(mst));
for(i =0; i < n; i++)
{
for(j = 0; j < n; j++)
{
g[i][j] = inf;
}
}
while(m--)
{
scanf("%d%d%d",&a,&b,&d);
if(g[a][b] > d)
g[a][b] = g[b][a] = d;
}
scanf("%d%d",&s,&t);
Dijkstra();
if(s == t)
cout<<"0"<<endl;
else{
if(low[t] < inf)
printf("%d\n",low[t]);
else
cout<<"-1"<<endl;
}
}
}
3.2 Floyd
for(int k = 0;k < n;k ++)
{
for(int i = 0;i < n;i ++)
{
for(int j = 0;j < n;j ++)
{
mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);
}
}
}