POJ 1847 Tram --set实现最短路SPFA

题意很好懂,但是不好下手。这里可以把每个点编个号(1-25),看做一个点,然后能够到达即为其两个点的编号之间有边,形成一幅图,然后求最短路的问题。并且pre数组记录前驱节点,print_path()方法可用算法导论上的。

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <set>

#define Mod 1000000007

#define INT 2147483647

#define pi acos(-1.0)

#define eps 1e-3

#define lll __int64

#define ll long long

using namespace std;

#define N 100007



const int INF = Mod;

vector<pair<int,int> > edge[N];

set<pair<int,int> > que;

int a[6][6],n;

int d[N],pre[N];



void print_path(int s,int v)

{

    if(v == s)

        printf("(%d, %d)\n",(s-1)/5,(s%5+5-1)%5);

    else

    {

        print_path(s,pre[v]);

        printf("(%d, %d)\n",(v-1)/5,(v%5+5-1)%5);

    }

}



int ok(int x,int y)

{

    if(x >= 0 && x < 5 && y >= 0 && y < 5)

        return 1;

    return 0;

}



void SPFA()

{

    int i;

    for(i=2;i<=n;i++)

        d[i] = INF;

    d[1] = 0;

    que.insert(make_pair(d[1],1));

    while(!que.empty())

    {

        int v = que.begin()->second;

        que.erase(que.begin());

        for(i=0;i<edge[v].size();i++)

        {

            int to = edge[v][i].first;

            int cost = edge[v][i].second;

            if(d[v] + cost < d[to])

            {

                que.erase(make_pair(d[to],to));

                d[to] = d[v] + cost;

                pre[to] = v;

                que.insert(make_pair(d[to],to));

            }

        }

    }

    print_path(1,n);

}



int main()

{

    int i,j;

    for(i=0;i<5;i++)

        for(j=0;j<5;j++)

            scanf("%d",&a[i][j]);

    for(i=0;i<5;i++)

    {

        for(j=0;j<5;j++)

        {

            if(a[i][j] == 0)

            {

                int ka = i*5 + j + 1,kb;

                if(ok(i+1,j) && a[i+1][j] == 0)

                {

                    kb = ka + 5;

                    edge[ka].push_back(make_pair(kb,1));

                }

                if(ok(i,j+1) && a[i][j+1] == 0)

                {

                    kb = ka+1;

                    edge[ka].push_back(make_pair(kb,1));

                }

                if(ok(i-1,j) && a[i-1][j] == 0)

                {

                    kb = ka-5;

                    edge[ka].push_back(make_pair(kb,1));

                }

                if(ok(i,j-1) && a[i][j-1] == 0)

                {

                    kb = ka-1;

                    edge[ka].push_back(make_pair(kb,1));

                }

            }

        }

    }

    n = 25;

    SPFA();

    return 0;

}
View Code

 

你可能感兴趣的:(SPFA)