POJ-图论-最短路模板(邻接矩阵)

POJ-图论-最短路模板

一、Floyd算法

刚读入数据时,G为读入的图邻接矩阵,更新后,G[i][j]表示结点i到结点j的最短路径长度

int G[N][N];//二维数组,其初始值即为该图的邻接矩阵

1.init():初始化图邻接矩阵

void init()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            G[i][j] = -1;//初始化邻接矩阵,用-1代表无穷
        }
        G[i][i] = 0;//初始化,自己到自己的路径长度为0
    }
}

2.floyd():更新最短路径

void floyd()
{
    for (int k = 1; k <= n; k++)//从1至n循环k
    {
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)//遍历所有的i,j
            {
                if (G[i][k] == -1 || G[k][j] == -1)continue;
                if (G[i][j] == -1 || G[i][k] + G[k][j] < G[i][j])G[i][j] = G[i][k] + G[k][j];
            }
        }
    }
}

例 5.5 最短路 

模板代码

#include<cstdio>
const int N = 105;
int G[N][N];
int n, m;

void init()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            G[i][j] = -1;//初始化为无穷
        }
    }
    for (int i = 1; i <= n; i++)G[i][i] = 0;//自己到自己距离是0
}

void floyd()
{
    for (int k = 1; k <= n; k++)
    {
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if (G[i][k] == -1 || G[k][j] == -1)continue;
                else if (G[i][j] == -1 || G[i][j] > G[i][k] + G[k][j])G[i][j] = G[i][k] + G[k][j];
            }
        }
    }
}

int main()
{
    while (scanf("%d%d", &n, &m) != EOF)
    {
        if (n == 0 && m == 0)break;
        init();
        int x, y, t;
        for (int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &x, &y, &t);
            G[x][y] = G[y][x] = t;
        }
        floyd();
        printf("%d
", G[1][n]);
    }
    return 0;
}

二、Dijkstra算法

G为图邻接矩阵,G[i][j]表示读入的i到j的距离,后面不再更新。d[]为距离数组,d[i]表示结点i到起点的最短距离。vis[N]为访问数组,记录各结点的访问情况。

int G[N][N]; // 图邻接矩阵
int d[N]; // 表示起点到各结点的最短距离
bool vis[N] = { false }; // 表示各结点被访问过与否

1.init():初始化邻接矩阵,到自身的距离为0

void init() // 初始化
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (i == j) G[i][j] = 0;
            else G[i][j] = INF;
        }
    }
}

2.Dijkstra(int start):初始化d[]之后,进行n次循环,每次先确定与起点直接相连的距离最小结点u及其距离d[u],再更新起点到其他结点v的距离d[v]。

void Dijkstra(int start)
{
    for (int i = 1; i <= n; i++) d[i] = INF;//可达距离都初始化为无穷
    d[start] = 0; // 起初只有start结点可达
    for (int i = 1; i <= n; i++)
    {
        int u = -1; // 距离最近的结点u,初始化为-1
        int min = INF; // min存放最小的d[u],初始化为无穷
        for (int j = 1; j <= n; j++)//得到最近的点
        {
            if (vis[j] == false && d[j] < min)
            {
                u = j; // 与起点直接相连的距离最小结点
                min = d[j];
            }
        }
        if (u == -1) return; // 说明剩下的未被访问过的结点都是与起点不可达的
        vis[u] = true; // 设为已读
        for (int v = 1; v <= n; v++)//由新得到的点更新后面所有点
        {
            // 此处d[u]有一个相加操作,所以在设置很大整数时不能设置为0x7fffffff,会导致溢出
            if (vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]) d[v] = d[u] + G[u][v];
        }
    }
}

 例 5.5 最短路 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 105;
const int INF = 0x3fffffff;
int n, m;
int G[N][N];
int d[N];//起点到各点的距离
bool vis[N] = { false };

void init()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            G[i][j] = INF;
        }
        G[i][i] = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        d[i] = INF;
        vis[i] = false;
    }
}

void djkstra(int start)
{
    d[start] = 0;
    for (int i = 1; i <= n; i++)//每次加入一个结点(这时连起点都还没加入)
    {
        int u = -1;//最近的结点
        int min = INF;//最近的距离值
        for (int j = 1; j <= n; j++)
        {
            if (vis[j] == false && d[j] < min)
            {
                min = d[j];
                u = j;
            }
        }
        if (u == -1)return;//无路可走
        vis[u] = true;
        for (int v = 1; v <= n; v++)//更新其他节点
        {
            if (vis[v] == false && G[u][v] != INF && d[v] > d[u] + G[u][v])d[v] = d[u] + G[u][v];
        }
    }
}

int main()
{
    while (scanf("%d%d", &n, &m) != EOF)
    {
        if (n == 0 && m == 0)break;
        init();
        for (int i = 0; i < m; i++)
        {
            int a, b, t;
            scanf("%d%d%d", &a, &b, &t);
            G[a][b] = G[b][a] = t;
        }
        djkstra(1);
        printf("%d
", d[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yun-an/p/11104314.html