PAT A1030 Travel Plan(30)

题意

  • 还是dijkstra最短路径题,路的边权分两个,distcost,第一标尺是dist最小,第二标尺是cost最小,此时唯一。

注意

  1. 这道题还要输出路径,所以为每个点记录前驱,最后来一个递归输出。

代码

#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;

const int Nmax = 500;
int N, M, S, D;
int dist[Nmax][Nmax];
int cost[Nmax][Nmax];

int m_dist[Nmax];
int m_cost[Nmax];
bool s[Nmax];
int v[Nmax];

void DIJKSTRA(int s0)
{
    fill(m_dist, m_dist + Nmax, INT_MAX);
    fill(s, s + Nmax, false);
    m_dist[s0] = 0;
    m_cost[s0] = 0;
    for (int i = 0; i < N; i++)
    {
        int min = INT_MAX, k;
        for (int j = 0; j < N; j++)
        {
            if (!s[j] && m_dist[j] < min)
            {
                min = m_dist[j];
                k = j;
            }
        }
        s[k] = true;
        for (int j = 0; j < N; j++)
        {
            if (!s[j] && dist[k][j] != INT_MAX)
            {
                if (m_dist[k] + dist[k][j] < m_dist[j])
                {
                    m_dist[j] = m_dist[k] + dist[k][j];
                    m_cost[j] = m_cost[k] + cost[k][j];
                    v[j] = k;
                }
                else if (m_dist[k] + dist[k][j] == m_dist[j] && m_cost[k] + cost[k][j] < m_cost[j])
                {
                    m_cost[j] = m_cost[k] + cost[k][j];
                    v[j] = k;
                }
            }
        }
    }
}

void PRINT(int d)
{
    if (d == S)
    {
        cout << d;
        return;
    }
    PRINT(v[d]);
    cout << " " << d;
}

int main()
{
    cin >> N >> M >> S >> D;
    int c1, c2;
    fill(dist[0], dist[0] + Nmax*Nmax, INT_MAX);
    for (int i = 0; i < M; i++)
    {
        cin >> c1 >> c2;
        cin >> dist[c1][c2];
        cin >> cost[c1][c2];
        dist[c2][c1] = dist[c1][c2];
        cost[c2][c1] = cost[c1][c2];
    }
    DIJKSTRA(S);
    PRINT(D);
    cout << " " << m_dist[D] << " " << m_cost[D];

    return 0;
}
posted @ 2017-02-10 19:02  CrossingOver  阅读(99)  评论(0编辑  收藏  举报