PTA Interstellar Adventure (25 points) (Dijkstra change constraints)

7-15 Interstellar Expedition (25 points)

In a certain distant future, the new human beings may undertake interstellar expeditions like this: There are several jumping points in the universe, and the human spacecraft can jump to other jumping points faster than the speed of light at each jumping point. Of course, generally speaking, each jump consumes a certain amount of energy, but because of the influence of unknown substances, certain jumps can instead obtain a certain amount of energy.

Among all jumping points, the original home of mankind-the earth is the most special. This is the only jumping point "not the destination of any jumping". In other words, you can jump from the earth to other points, but from any other point. No point can jump to the earth.

Suppose there is a spacecraft starting from the earth to start an interstellar expedition, taking into account the travel cost, set the upper limit of energy consumption when reaching the destination, then there are some jumping points that the spacecraft can reach under this energy consumption limit, and some The jumping point cannot be reached. Now please program to find all jumping points that can be reached.

Points to note:

  1. A reachable jumping point means that when the spacecraft arrives at this point, the energy consumption is within the limit; all reachable points refer to the collection of such points, rather than referring to the spacecraft’s journey on a single trip. Passing point. For example, if the spacecraft departs from the earth, if the energy limit is only enough to jump to one of the two points of Proxima Centauri or Sirius, and cannot reach these two points in a single trip, but "all reachable points" include this Two points, that is, from the point of view of jumping ability, these two points are "reachable".
  2. Certain jumps can increase the energy of the spacecraft, and there is a possibility: starting from a certain point, after several jumps, returning to this point. But the law of energy determines: When returning to this point, the spacecraft's energy can only be lower than when it originally started from this point (otherwise there will be "perpetual motion machines").
  3. The upper limit of energy consumption judges the energy consumed when reaching the destination (a certain jumping point), regardless of the energy state of the halfway point. It should be noted that some jumps will increase energy, so this situation is completely possible: when jumping to point A, the energy consumption exceeds the limit, but jumping from point A to point B happens to increase energy, and when jumping to point B, the total energy consumption Do not exceed the limit. At this time point A is considered unreachable and point B is reachable.

Input format:

First, give a positive integer N (N<=2000) in a row, which is the number of jumping points in the universe.

In the next N lines, the i-th line (i=1...N) describes the information of the jumping point numbered i in the following format:

k p1 d1 p2 d2… pk dk (separated by spaces)

Among them: the integer k is the number of jumps to other points starting from this jumping point, the following k is a non-zero integer pi di, pi represents the number of a certain point that can be jumped to, and di represents the energy of the spacecraft jumping to point pi Change, if di is positive, it means that this jump will increase energy (increase di), di is negative, it means that this jump will consume energy (the value of consumption is |di|). The question guarantees that the absolute value of the sum of energy consumed (or increased) from the earth to any reachable jumping point does not exceed 108.

The last line gives a positive integer E, which represents the upper limit of energy consumption set when the spacecraft sets off.

Output format:

Output the numbers of all jump points that the spacecraft can reach in the order of numbers from small to large, and output one number per line (with a line break at the end of the line).

prompt:

  1. The jumping point "Earth" is always considered "reachable", and it does not require energy to reach this point because it is the starting point).
  2. The number of the earth is not necessarily 1.

Input sample:

Here is a set of inputs. E.g:

6
3 2 -3 4 -5 3 -6
1 6 -6
2 4 -2 5 -2
2 3 -3 6 -3
1 4 4
0
7

Sample output:

The corresponding output is given here. E.g:

1
2
3
4
6

Problem solving

The topic uses the Dijkstra algorithm as the shortest path, but each node may be repeatedly visited, just remove the vis[] tag array.

Code

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
using namespace std;
const int maxn = 2002;
bool vis[maxn];
bool F[maxn][maxn];
int G[maxn][maxn], dist[maxn];
set<int> ans;

struct node {
    
    
    int id, va;
};

struct cmp {
    
    
    bool operator()(const node& a, const node& b) {
    
     return a.va > b.va; }
};

int getStart(int N) {
    
    
    for (int i = 1; i <= N; i++)
        if (!vis[i]) return i;
    return 0;
}

void Dijkstra(int start, int N, int E) {
    
    
    priority_queue<node, vector<node>, cmp> q;
    memset(dist, 0x3f, sizeof(dist));
    memset(vis, false, sizeof(vis));
    dist[start] = 0;
    q.push({
    
    start, dist[start]});
    while (!q.empty()) {
    
    
        int v = q.top().id;
        int va = q.top().va;
        q.pop();
        // if (vis[v]) continue;
        vis[v] = true;
        for (int i = 1; i <= N; i++) {
    
    
            if (F[v][i]) {
    
    
                // cout << v << " " << i << endl;
                if (dist[v] + G[v][i] < dist[i]) {
    
    
                    dist[i] = dist[v] + G[v][i];
                    q.push({
    
    i, dist[i]});
                }
            }
        }
    }
    for (int i = 1; i <= N; i++) {
    
    
        // cout << dist[i] << " ";
        if (dist[i] <= E) ans.insert(i);
    }
    // cout << endl;
}

int main() {
    
    
    int N, k, E;
    cin >> N;
    for (int i = 1; i <= N; i++) {
    
    
        cin >> k;
        int p, d;
        for (int j = 1; j <= k; j++) {
    
    
            cin >> p >> d;
            vis[p] = true;
            F[i][p] = true;
            G[i][p] = -d;
        }
    }
    cin >> E;
    int start = getStart(N);
    memset(vis, false, sizeof(vis));
    Dijkstra(start, N, E);
    for (auto i = ans.begin(); i != ans.end(); i++) {
    
    
        cout << *i << endl;
    }

    system("pause");
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_45349225/article/details/109501715