1. 程式人生 > 其它 >最短路————杭電OJ

最短路————杭電OJ

技術標籤:dijkstra圖論演算法c++程式設計

題目連結
http://acm.hdu.edu.cn/showproblem.php?pid=1874
思路
套板子的最短路,熟悉板子的題目。

Floyd程式碼

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>

using namespace std;

const int INF=0x3f3f3f3f;
const int N=110;

int n,m;
int d[N][N];
void floyd(
) { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(d[i][j]>d[i][k]+d[k][j]) { d[i][j]=d[i][k]+d[k][j]; } } } } } int main
() { while(1) { scanf("%d%d",&n,&m); if(n==0&&m==0) { break; } else { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if
(i==j) d[i][j]=0; else { d[i][j]=INF; } } } for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(d[a][b]>c) { d[a][b]=d[b][a]=c; } } floyd(); printf("%d\n",d[1][n]); } } return 0; }

樸素Dijkstra程式碼

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>

using namespace std;

const int INF=0x3f3f3f3f;
const int N=110;

int n,m;
int g[N][N];
int vis[N],dis[N];

void Dijkstra(){
    memset(dis, 0x3f, sizeof(dis));

    for(int i = 1 ; i <= n ; i ++)
    {
        dis[i] = g[1][i];//初始化指定起點到其它點的距離
    }
    dis[1] = 0;
    vis[1] = 1;
    for (int i = 1; i <= n - 1; i ++ )
    {
        int t = -1;     // 在還未確定最短路的點中,尋找距離最小的點
        for (int j = 1; j <= n; j ++ )
            if (!vis[j] && (t == -1 || dis[t] > dis[j]))
                t = j;

        // 用t更新其他點的距離
        for (int j = 1; j <= n; j ++ )
            dis[j] = min(dis[j], dis[t] + g[t][j]);

        vis[t] = 1;
    }
}
int main()
{
    while(1)
    {
        scanf("%d%d",&n,&m);
        if(n==0&&m==0)
        {
            break;
        }
        else
        {    
            memset(vis,0,sizeof(vis));
            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;
                    }
                    
                }
            }
            for(int i=0;i<m;i++)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                getchar();
                if(g[a][b]>c)
                {
                    g[a][b]=g[b][a]=c;
                }
            }
            Dijkstra();
            printf("%d\n",dis[n]);
        }
    }
    return 0;
}

SPFA程式碼

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>

using namespace std;

const int INF=0x3f3f3f3f;
const int N=110;

int n,m;
int g[N][N];
int vis[N],dis[N];

void SPFA(){
    memset(dis, 0x3f, sizeof(dis));
    
    dis[1] = 0;
    vis[1] = 1;
    
    queue<int> q;

    q.push(1);

    while(q.size())
    {
        auto t=q.front();
        q.pop();

        vis[t]=0;

        for(int i=1;i<=n;i++)
        {
            if(dis[i]>dis[t]+g[t][i])
            {
                dis[i]=dis[t]+g[t][i];
                if(!vis[i])
                {
                    vis[i]=1;
                    q.push(i);
                }
            }
        }
    }
}
int main()
{
    while(1)
    {
        scanf("%d%d",&n,&m);
        if(n==0&&m==0)
        {
            break;
        }
        else
        {
            memset(vis,0,sizeof(vis));
            memset(g,INF,sizeof(g));
            for(int i=0;i<m;i++)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                getchar();
                if(g[a][b]>c)
                {
                    g[a][b]=g[b][a]=c;
                }
            }
            SPFA();
            printf("%d\n",dis[n]);
        }
    }
    return 0;
}