赞
踩
在某个遥远的未来,新新人类将可能这样进行星际探险:宇宙中分布着若干个跳跃点,人类飞船在每个跳跃点可超光速跳至其它跳跃点。当然,一般来说每次跳跃是要消耗一定能量的,但因为有未知物质的影响,某些跳跃反而可以获得一定能量。
在所有跳跃点中,人类的原始家园——地球最具特殊性,这是唯一一个“不是任何跳跃的目的地”的跳跃点,换句话说,从地球可以跳到其它点,但是从任何其它点都不能跳到地球。
假设有一艘飞船从地球出发开始星际探险之旅,考虑到旅行成本,设定在到达目的地时能量的消耗上限,那么有一些跳跃点是飞船在这个能量消耗限制下能够抵达的,而有一些跳跃点是无法抵达的。现在请你编程找出所有能够抵达的跳跃点。
需要注意的几点:
首先在一行中给出正整数N(N<=2000),是宇宙中跳跃点的数量。
接下来N行,第i行(i=1…N)按以下格式描述编号为i的跳跃点的信息:
k p1 d1 p2 d2 … pk dk (以空格间隔)
其中:整数k是从这个跳跃点出发,能跳到其它点的数量,之后的k对非零整数pi di,pi表示能跳到的某个点的编号,di表示飞船跳到pi点的能量变化,如果di为正表示这个跳跃会增加能量(增加di),di为负表示这个跳跃要消耗能量(消耗的值为|di|)。题目保证从地球到任何一个可以抵达的跳跃点,沿途消耗(或增加)的能量之和的绝对值不超过108。
最后一行给出正整数E,表示飞船出发时设置的能量消耗上限。
按照编号从小到大的顺序输出飞船所有能够抵达的跳跃点编号,每行输出一个编号(行末有换行符)。
在这里给出一组输入。例如:
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
在这里给出相应的输出。例如:
1
2
3
4
6
题目采用Dijkstra算法就最短路径,但是每个节点可能会重复访问,只需把vis[]标记数组去掉即可。
#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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。