51 nod: 1459 Maze game

topic

You come to a maze. The maze consists of several rooms, each room has a score, you can get this score when you enter this room for the first time. There are also several two-way roads connecting these rooms, and it takes some time for you to walk from one room to the other along these roads. The game stipulates your starting and ending rooms. Your primary goal is to get from the starting point to the end point as soon as possible. On the premise of meeting the primary goal, make your total score as large as possible. Now the question is, given all the information about the room, the road, the score, the starting point and the ending point, can you calculate the maximum score you can get out of the maze as soon as possible?

Input

The first line has 4 integers n (<=500), m, start, end. n represents the number of rooms, the room number is from 0 to (n - 1), m represents the number of roads, there is at most one road between any two rooms, and start and end represent the numbers of the starting and ending rooms.
The second line contains n space-separated positive integers (up to 600) representing your score for entering each room.
Next m lines, each with 3 space-separated integers x, y, z (0

Output

One line, two space-separated integers, the first is the minimum time you need, and the second is the maximum score you can get with the minimum time.

Input example

3 2 0 2
1 2 3
0 1 10
1 2 11

Output example

21 6

answer

This problem is dijkstraa small modification of the algorithm of the shortest path. When we search for the minimum path, we not only need to update the length of the shortest path, but when the path lengths are the same, we need to compare the values ​​of the two and choose the larger one. Others are the same as the traditional dijkstraalgorithm.

cntValue[i]=max(cntVa l u e [ i dx]+val[i],cntVa l u e [ i ] ) ;

code

#include <iostream>
#include <vector>
#include <limits>
#include <algorithm>
#include <cstring>

using namespace std;

int main()
{
    int n, m, start, end;    // n代表点数,m代表路径数
    cin >> n >> m >> start >> end;
    vector<int> val(n);        // 记录每个节点的值
    for (int i = 0; i < n; ++i)
        cin >> val[i];
    vector<vector<int> > mat(n, vector<int>(n, -1));
    int x, y, v;
    for (int i = 0; i < m; ++i)
    {
        cin >> x >> y >> v;
        mat[x][y] = mat[y][x] = v;
    }
    vector<int> d(n,INT_MAX);                // 记录路径长度
    vector<bool> visit(n, false);    // 用于标记是否访问过
    vector<int> cntValue(n,0);        // 记录可以得到的最大值
    d[start] = 0;                    // 初始化起点的距离,访问标记,累计value
    visit[start] = true;
    cntValue[start] = val[start];
    int idx = start;
    for (int i = 0; i < n; ++i)
    {
        if (!visit[i] && mat[idx][i] >= 0)        // 更新距离
        {            
            if (d[idx] + mat[idx][i] == d[i])        // 注意距离相等时选择较大的val
            {
                cntValue[i] = max(cntValue[idx] + val[i], cntValue[i]);        // 更新累计值
            }
            if (d[idx] + mat[idx][i] < d[i])
            {
                d[i] = d[idx] + mat[idx][i];
                cntValue[i] = cntValue[idx] + val[i];
            }
        }
    }
    while (true)
    {
        int maxLen = INT_MAX;
        // 查找最小的d
        for (int i = 0; i < n; ++i)
        {
            if (!visit[i] && d[i] < maxLen)
            {
                maxLen = d[i];
                idx = i;
            }
        }
        if (idx == end)
            break;            // 找到了退出
        visit[idx] = true;  // 标记变量        
        for (int i = 0; i < n; ++i)
        {
            if (!visit[i] && mat[idx][i] >= 0)        // 更新距离
            {
                //d[i] = min(d[i], d[idx] + mat[start][i]);
                if (d[idx] + mat[idx][i] == d[i])
                {                    
                    cntValue[i] = max(cntValue[idx] + val[i], cntValue[i]);        // 更新累计值
                }
                if (d[idx] + mat[idx][i]<d[i])
                {
                    d[i] = d[idx] + mat[idx][i];
                    cntValue[i] = cntValue[idx] + val[i];
                }
            }
        }
    }
    cout << d[end] << " " << cntValue[end] << endl;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325766839&siteId=291194637