数据结构-最小生成树与最短路

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]);
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/xiaomingds/article/details/106201733