汤姆斯的天堂梦(C++,Dijkstra)
创始人
2024-05-09 19:40:58
0

题目描述

汤姆斯生活在一个等级为 000 的星球上。那里的环境极其恶劣,每天 121212 小时的工作和成堆的垃圾让人忍无可忍。他向往着等级为 NNN 的星球上天堂般的生活。

有一些航班将人从低等级的星球送上高一级的星球,有时需要向驾驶员支付一定金额的费用,有时却又可以得到一定的金钱。

汤姆斯预先知道了从 000 等级星球去 NNN 等级星球所有的航线和需要支付(或者可以得到)的金钱,他想寻找一条价格最低(甚至获得金钱最多)的航线。

输入格式

第一行一个正整数 NNN(N≤100N \le 100N≤100),接下来的数据可分为 NNN 个段落,每段的第一行一个整数 KiK_iKi​(Ki≤100K_i \le 100Ki​≤100),表示等级为 iii 的星球有 KiK_iKi​ 个。

接下来的 KiK_iKi​ 行中第 jjj 行依次表示与等级为 iii,编号为 jjj 的星球相连的等级为 i−1i - 1i−1 的星球的编号和此航线需要的费用(正数表示支出,负数表示收益,费用的绝对值不超过 100010001000)。

每行以 000 结束,每行的航线数 ≤100\le 100≤100。

输出格式

输出所需(或所得)费用。正数表示支出,负数表示收益。

样例 #1

样例输入 #1

3
2
1 15 0
1 5 0
3
1 -5 2 10 0
1 3 0
2 40 0
2
1 1 2 5 3 -5 0
2 -19 3 -20 0

样例输出 #1

-1

提示

对于 100%100 \%100% 的数据,1≤N≤1001 \le N \le 1001≤N≤100,1≤Ki≤1001 \le K_i \le 1001≤Ki​≤100。

样例解释:

解题思路:

先介绍一下Dijkstra思想(已经了解可以跳过)其实质是贪心Dijkstra将所有点划分为两个点集其中最短路径集里所有点的最短路径均是已知的最初,所有的点均属于非最短路径集首先将起点加入到最短路径集然后尝试从起点能够到达的所有点将其中路径最短的点加入到最短路径集,然后尝试从新的点能够到达的所有点再次把已尝试过所有路径中路径最短的点加入最短路径集,然后循环上述步骤注意,是尝试过的所有路径中,而不是第二次尝试的路径中

单源最短路径,可以想到使用Dijkstra,但鉴于输入数据的特殊性,还需要做一些处理

首先,注意到本题每个节点是由等级和编号唯一确定的

但是我们仍可将其抽象为唯一的编号,如样例中的点可以标号为111~888

然后,注意到本题中的边权可能为负数,要知道Dijkstra中的边权不能为负

所有边权整体加上一个偏移量即可

那么存图的问题解决了,接下来就是套用Dijkstra算法了

AC代码如下

#include 
#include 
#include 
#include 
using namespace std;
const int max_n = 100;
const int max_k = 100;
const int max_m = 100;
const int NaN = 0x3F3F3F3F;class greater_queue {
public:bool operator()(pairp_1, pairp_2) {return p_1.first > p_2.first;}
};priority_queue, vector>, greater_queue>p_q;
struct edge { int v, p, next; }edges[max_n * max_k * max_m];//链式前向星
int head[max_n * max_k + 2] = { -1 };
int tot = -1;
int min_dist[max_n * max_k + 2] = { NaN };
bool book[max_n * max_k + 2] = { false };//最短路径集void add_edge(int u, int v, int p) {//存图edges[++tot] = { v,p,head[u] }; head[u] = tot;
}void dijkstra() {min_dist[1] = 0;p_q.push(pair(0, 1));//初始化while (!p_q.empty()) {int node = p_q.top().second;int dist = p_q.top().first;p_q.pop();if (book[node]) continue;//已加入最短路径集book[node] = true;//未加入最短路径集for (int i = head[node]; i != -1; i = edges[i].next) {//尝试更新最短路径int v = edges[i].v;if (min_dist[v] > edges[i].p + dist) {min_dist[v] = edges[i].p + dist;p_q.push(pair(min_dist[v], v));}}}
}int main() {memset(head + 1, -1, sizeof(int) * (max_n * max_k + 1));memset(min_dist + 1, 0x3F, sizeof(int) * (max_n * max_k + 1));//初始化int n, k, u, p, cur_tot = 1, temp_tot = 0;cin >> n;for (int i = 1; i <= n; i++) {//存图cin >> k;for (int j = 1; j <= k; j++) {++cur_tot;//节点分配while (true) {cin >> u;if (u == 0) break;//行尾cin >> p;add_edge(temp_tot + u, cur_tot, p + 1000);//边权偏移}}temp_tot = cur_tot - k;//寻访i-1级星球}dijkstra();int ans = NaN;for (int i = temp_tot + 1; i <= cur_tot; i++) {//寻找最小值ans = min(ans, min_dist[i]);}cout << ans - 1000 * n << endl;//平衡偏移、输出return 0;
}

相关内容

热门资讯

【光明论坛】城市工作是高质量发...   【光明论坛】  作者:张影(北京大学光华管理学院副院长)  日前召开的中央政治局会议指出,落实好...
净网—2025丨为牟私利,编造...   招生入学工作是保障教育公平的关键环节,事关群众的切身利益,容不得任何歪曲解读。  近日,云南昭通...
声动中国|沿着北纬30°,寻找...   蝉鸣渐弱,暑气将熄  夏日的倒计时悄然归零  人间烟火却在这北纬30°的纬线上  续写着不息的炽...
勇立潮头大湾区丨打造“智慧全运...   第十五届全国运动会  已进入百日倒计时  炎炎夏日的广州  热浪翻涌  近百个全运会志愿者服务站...
何以中国 | 天津: 从“依河...   策划|天津日报《学习周刊》 津云新媒体要闻中心  编辑|王聪 董琳晶  设计|李博婷
冷资源化身热产业,青海外贸跑出...   上半年,中国外贸增速第一省是青海。  今年上半年,青海省完成进出口总值35.9亿元,同比增57....
境外间谍窃取面容数据,渗透到涉... 在数字化时代的浪潮中,生物特征识别技术凭借准确性和便捷性得到快速发展和广泛应用。通过生物特征识别技术...
“清凉经济”火热一夏 滑雪场、...   最近,全国多地依然高温持续,暑期消费市场却逆势吹起了一阵“清凉风”。吉林省,夏季全域平均温度22...
暑期文旅里的“融”字诀(评论员...   建设全国统一大市场是构建新发展格局、推动高质量发展的需要。7月30日召开的中央政治局会议指出:“...
警惕!不法分子利用中小学生实施...   租借学生微信号、盗取儿童电话卡、以“兼职”名义诱导拨打诈骗电话  警惕!不法分子利用中小学生实施...