PAT (Advanced Level) Practice A1111 Online Map (30 分)(C++)(甲级)(Dijkstra)

原题链接

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

typedef struct Node
{
    int len, time;
}Node;

const int MAX = 510, INF = (1<<30)-1;
int N, M, source, destination;
int V1, V2, one_way, L, T;
Node G[MAX][MAX] = {{0}};
int d[MAX], t[MAX];
vector<int> preD[MAX], preT[MAX];

void DijkstraD(int s)
{
    bool visited[MAX] = {0};
    fill(d, d+MAX, INF);
    d[s] = 0;
    for(int i=0; i<N; i++)
    {
        int MIN = INF, u = -1;
        for(int v=0; v<N; v++)
        {
            if(!visited[v] && d[v] < MIN)
            {
                MIN = d[v];
                u = v;
            }
        }
        if(u == -1) return ;
        visited[u] = true;
        for(int v=0; v<N; v++)
        {
            if(!visited[v] && G[u][v].len != INF)
            {
                if(d[u] + G[u][v].len < d[v])
                {
                    d[v] = d[u] + G[u][v].len;
                    preD[v].clear();
                    preD[v].push_back(u);
                }
                else if(d[u] + G[u][v].len == d[v])
                {
                    preD[v].push_back(u);
                }
            }
        }
    }
}
void DijkstraT(int s)
{
    bool visited[MAX] = {0};
    fill(t, t+MAX, INF);
    t[s] = 0;
    for(int i=0; i<N; i++)
    {
        int MIN = INF, u = -1;
        for(int v=0; v<N; v++)
        {
            if(!visited[v] && t[v] < MIN)
            {
                MIN = t[v];
                u = v;
            }
        }
        if(u == -1) return ;
        visited[u] = true;
        for(int v=0; v<N; v++)
        {
            if(!visited[v] && G[u][v].time != INF)
            {
                if(t[u] + G[u][v].time < t[v])
                {
                    t[v] = t[u] + G[u][v].time;
                    preT[v].clear();
                    preT[v].push_back(u);
                }
                else if(t[u] + G[u][v].time == t[v])
                {
                    preT[v].push_back(u);
                }
            }
        }
    }
}

vector<int> temp, shortest_path, fastest_path;
long long int min_time = INF;

void DFS_shortest(int v)//从最短路程中选择最短时间
{
    if(v == source)
    {
        temp.push_back(v);
        long long int value = 0;
        for(int i=temp.size()-1; i>0; i--)
        {
            value += G[temp[i]][temp[i-1]].time;
        }
        if(value < min_time)
        {
            min_time = value;
            shortest_path = temp;
        }
        temp.pop_back();
    }
    temp.push_back(v);
    for(int i=0; i<preD[v].size(); i++)
    {
        DFS_shortest(preD[v][i]);
    }
    temp.pop_back();
}
void DFS_fastest(int v)//最短时间里选择最少交汇点
{
    if(v == source)
    {
        temp.push_back(v);
        if(!fastest_path.size() || temp.size() < fastest_path.size())
        {
            fastest_path = temp;
        }
        temp.pop_back();
    }
    temp.push_back(v);
    for(int i=0; i<preT[v].size(); i++)
    {
        DFS_fastest(preT[v][i]);
    }
    temp.pop_back();
}


int main()
{
    Node t_INF = {INF, INF};
    fill(G[0], G[0]+MAX*MAX, t_INF);
    scanf("%d %d", &N, &M);
    for(int i=0; i<M; i++)
    {
        scanf("%d %d %d %d %d", &V1, &V2, &one_way, &L, &T);
        G[V1][V2].len = L, G[V1][V2].time = T;
        if(!one_way) G[V2][V1].len = L, G[V2][V1].time = T;
    }
    scanf("%d %d", &source, &destination);
    DijkstraD(source);
    DFS_shortest(destination);
    DijkstraT(source);
    DFS_fastest(destination);
    if(shortest_path == fastest_path)
    {
        printf("Distance = %d; Time = %d: ", d[destination], t[destination]);
        printf("%d", fastest_path[fastest_path.size()-1]);
        for(int i=fastest_path.size()-2; i>=0; i--)
        {
            printf(" -> %d", fastest_path[i]);
        }
    }
    else
    {
        printf("Distance = %d: ", d[destination]);
        printf("%d", shortest_path[shortest_path.size()-1]);
        for(int i=shortest_path.size()-2; i>=0; i--)
        {
            printf(" -> %d", shortest_path[i]);
        }
        printf("\n");
        printf("Time = %d: ", t[destination]);
        printf("%d", fastest_path[fastest_path.size()-1]);
        for(int i=fastest_path.size()-2; i>=0; i--)
        {
            printf(" -> %d", fastest_path[i]);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值