SPFA算法 最短路

spfa求最短路

有一篇讲解spfa的博客,讲的不错:最快最好用的——spfa算法

POJ 2387  Til the Cows Come Home

最短路裸题

input:

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

output:

90

直接模拟spfa算法过程:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define M 2009
#define INF 0x3f3f3f3f
bool vis[M];
int dis[M];
int map[M][M];
int n,m;
void spfa(int s)
{
    for(int i = 1;i <= n;i++)
    {
        dis[i] = INF;
        vis[i] = false;
    }
    dis[s] = 0;
    queue<int> q;
    q.push(s);
    vis[s] = true;
    while(!q.empty())
    {
        s = q.front();
        vis[s] = false;
        q.pop();
        for(int i=1;i<=n;i++)
        {
            if(map[s][i]==INF)
                continue;
            if(i==s)
                continue;
            if(dis[i]>dis[s]+map[s][i])
            {
                dis[i]=dis[s]+map[s][i];
                if(!vis[i])
                {
                    vis[i]=true;
                    q.push(i);
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&m,&n))  //n是顶点数,m是边数
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(i==j)
                    map[i][j]=0;
                else
                    map[i][j]=INF;
            }
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            if(c<map[a][b])
                map[a][b]=map[b][a]=c;
        }
        spfa(1);
        //输出点1到点n的最短路是多少
        printf("%d\n",dis[n]);
    }
    return 0;
}


vector实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define M 2009
#define INF 0x3f3f3f3f
struct edge
{
    int to,w;
};
bool inq[M];
vector <edge> g[M];     //g[i]表示i点到g[i].to这个点的距离是g[i].w
int dis[M];
int n,m;
void spfa(int s)
{
    for(int i = 1;i <= n;i++)
    {
        dis[i] = INF;
        inq[i] = false;
    }
    dis[s] = 0;
    queue<int> q;
    q.push(s);
    inq[s] = true;
    while(!q.empty())
    {
        s = q.front();
        inq[s] = false;
        q.pop();
        for(int i = 0;i < g[s].size();i++)
        {
            int v = g[s][i].to;
            int w = g[s][i].w;
            if(dis[v] > dis[s]+w)
            {
                dis[v] = dis[s]+w;
                if(!inq[v])
                {
                    inq[v] = true;
                    q.push(v);
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d %d",&m,&n))  //n是顶点数,m是边数
    {
        for(int i = 1;i <= n;i++)
            g[i].clear();
        for(int i = 0;i < m;i++)
        {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c); //多条边的话,暂时不知道怎么处理,但是这道题的数据里也有多条边,难道是用vector不用管多条边,不清楚
            edge e;
            e.to = b;e.w = c;
            g[a].push_back(e);
            e.to = a;
            g[b].push_back(e);  //无向图 变化成双向的。
        }
        spfa(n);
        printf("%d\n",dis[1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/flyzer/article/details/80653811