PAT(A) 1111. Online Map (30)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huqiao1206/article/details/79511098

原题目:

原题链接:https://www.patest.cn/contests/pat-a-practise/1111

1111. Online Map (30)


Input our current position and a destination, an online map can recommend several paths. Now your job is to recommend two paths to your user: one is the shortest, and the other is the fastest. It is guaranteed that a path exists for any request.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (2 <= N <= 500), and M, being the total number of streets intersections on a map, and the number of streets, respectively. Then M lines follow, each describes a street in the format:

V1 V2 one-way length time

where V1 and V2 are the indices (from 0 to N-1) of the two ends of the street; one-way is 1 if the street is one-way from V1 to V2, or 0 if not; length is the length of the street; and time is the time taken to pass the street.

Finally a pair of source and destination is given.

Output Specification:

For each case, first print the shortest path from the source to the destination with distance D in the format:

Distance = D: source -> v1 -> … -> destination

Then in the next line print the fastest path with total time T:

Time = T: source -> w1 -> … -> destination

In case the shortest path is not unique, output the fastest one among the shortest paths, which is guaranteed to be unique. In case the fastest path is not unique, output the one that passes through the fewest intersections, which is guaranteed to be unique.

In case the shortest and the fastest paths are identical, print them in one line in the format:

Distance = D; Time = T: source -> u1 -> … -> destination

Sample Input 1:
10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
3 4 0 3 2
3 9 1 4 1
0 6 0 1 1
7 5 1 2 1
8 5 1 2 1
2 3 0 2 2
2 1 1 1 1
1 3 0 3 1
1 4 0 1 1
9 7 1 3 1
5 1 0 5 2
6 5 1 1 2
3 5
Sample Output 1:
Distance = 6: 3 -> 4 -> 8 -> 5
Time = 3: 3 -> 1 -> 5
Sample Input 2:
7 9
0 4 1 1 1
1 6 1 1 3
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 1 3
3 2 1 1 2
4 5 0 2 2
6 5 1 1 2
3 5
Sample Output 2:
Distance = 3; Time = 4: 3 -> 2 -> 5

题目大意

给出一个图,求最短路。输入首行为N,M表示节点数和路径数。
后M行v1,v2,oneway,length,time表示一条路径信息,oneway为1表示单行道,为0表示双行道。

1. 由s到d之间长度最短的路,若存在长度相同的,选取时间较短的。
1. 由s到d之间耗时最短的路,若存在耗时相等的,选取节点数最少的。

解题报告

最短路的题,权值比较方式不同了,使用dijkstra算法。
碰到坑:
1. 当时间相同时,选取的不一定是其中路径长度短的,是途经节点少的。
1. dijkstra中,选取尚未到达的点时,临时存储的变量写的费事了点,刚开始时写错了。

代码

/*
* Problem: 1111. Online Map (30)
* Author: HQ
* Time: 2018-03-10
* State: Done
* Memo: Dijkstra
*/
#include "iostream"
#include "string"
#include "vector"
#include "climits"
#include "stack"
using namespace std;

struct NodeRoute {
    int pre;
    int dis;
    int time;
};

struct Node {
    int data;
    int dis;
    int time;
};

vector<NodeRoute> dis, tim;
vector<vector<Node>> map;
vector<bool> visit;
int N, M;
int s, d;

void init() {
    cin >> N >> M;
    map.resize(N);
    int v1, v2, one, length, time;
    for (int i = 0; i < M; i++) {
        cin >> v1 >> v2 >> one >> length >> time;
        Node temp;
        temp.data = v2;
        temp.dis = length;
        temp.time = time;
        map[v1].push_back(temp);
        if (!one) {
            temp.data = v1;
            map[v2].push_back(temp);
        }
    }
    cin >> s >> d;
}

bool isgooder(int x, NodeRoute *gooder, bool DOrT) { // D:1 T:0
    if (DOrT) {
        if (dis[x].dis != gooder->dis)
            return dis[x].dis < gooder->dis;
        return dis[x].time < gooder->time;
    }
    else {
        if (tim[x].time != gooder->time)
            return tim[x].time < gooder->time;
        return tim[x].dis < gooder->dis;
    }
}

void dijD() {
    int k = s;
    dis.resize(N, { -1, INT_MAX,INT_MAX });
    dis[s] = { s,0,0 };
    visit[s] = true;
    NodeRoute *gooder;
    NodeRoute temp = { -1, INT_MAX,INT_MAX };
    for (int i = 0; i < N; i++) {
        gooder = &temp;
        for (int j = 0; j < N; j++)
            if (!visit[j] && isgooder(j, gooder, true)) {
                k = j;
                gooder = &dis[k];
            }
        visit[k] = true;
        for (int j = 0; j < map[k].size(); j++) {
            if (dis[k].dis + map[k][j].dis < dis[map[k][j].data].dis) {
                dis[map[k][j].data].pre = k;
                dis[map[k][j].data].dis = dis[k].dis + map[k][j].dis;
                dis[map[k][j].data].time = dis[k].time + map[k][j].time;
            }
            else if (dis[k].dis + map[k][j].dis == dis[map[k][j].data].dis) {
                if (dis[k].time + map[k][j].time < dis[map[k][j].data].time) {
                    dis[map[k][j].data].pre = k;
                    dis[map[k][j].data].dis = dis[k].dis + map[k][j].dis;
                    dis[map[k][j].data].time = dis[k].time + map[k][j].time;
                }
            }
        }
    }
}
void dijT() {
    int k = s;
    tim.resize(N, { -1, INT_MAX,INT_MAX });
    tim[s] = { s,0,0 };
    visit[s] = true;
    NodeRoute *gooder;
    NodeRoute temp = { -1, INT_MAX,INT_MAX };
    for (int i = 0; i < N; i++) {
        gooder = &temp;
        for (int j = 0; j < N; j++)
            if (j != s && !visit[j] && isgooder(j, gooder, false)) {
                k = j;
                gooder = &tim[k];
            }
        visit[k] = true;
        for (int j = 0; j < map[k].size(); j++) {
            if (tim[k].time + map[k][j].time < tim[map[k][j].data].time) {
                tim[map[k][j].data].pre = k;
                tim[map[k][j].data].dis = tim[k].dis + 1;
                tim[map[k][j].data].time = tim[k].time + map[k][j].time;
            }
            else if (tim[k].time + map[k][j].time == tim[map[k][j].data].time) {
                if (tim[k].dis + 1 < tim[map[k][j].data].dis) {
                    tim[map[k][j].data].pre = k;
                    tim[map[k][j].data].dis = tim[k].dis + 1;
                    tim[map[k][j].data].time = tim[k].time + map[k][j].time;
                }
            }
        }
    }

}

bool isOne() {
    int i = d, j = d;
    while (i != s || j != s) {
        if(dis[i].pre == tim[i].pre){
            i = dis[i].pre;
            j = tim[j].pre;
        }
        else
            return false;
    }
    if (i != j)
        return false;
    else
        return true;
}

void printAns(bool one) {
    stack<int> ans;
    if (one) {
        for (int i = d; i != s; ) {
            ans.push(i);
            i = dis[i].pre;
        }
        printf("Distance = %d; Time = %d: %d", dis[d].dis, tim[d].time,s);
        while (!ans.empty()) {
            printf(" -> %d", ans.top());
            ans.pop();
        }
    }
    else {
        for (int i = d; i != s; ) {
            ans.push(i);
            i = dis[i].pre;
        }
        printf("Distance = %d: %d", dis[d].dis, s);
        while (!ans.empty()) {
            printf(" -> %d", ans.top());
            ans.pop();
        }
        for (int i = d; i != s; ) {
            ans.push(i);
            i = tim[i].pre;
        }
        printf("\nTime = %d: %d", tim[d].time, s);
        while (!ans.empty()) {
            printf(" -> %d", ans.top());
            ans.pop();
        }
    }
}

int main() {
    init();
    visit.resize(N, false);
    dijD();
    visit.clear();
    visit.resize(N, false);
    dijT();
    printAns(isOne());
    system("pause");
}

猜你喜欢

转载自blog.csdn.net/huqiao1206/article/details/79511098