最短路

  • 7-2 旅游规划 (25分)
  • 7-4 城市间紧急救援 (25分)

7-2 旅游规划 (25分)

https://pintia.cn/problem-sets/1305331769412022272/problems/1305332680884613121
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输出样例:
3 40
oj上好像有一个跟这个差不多的题,用了两种做法,一个A,一个W。。。

代码精简版:floyd:

#include <stdio.h>
#include <stdlib.h>
#define max 999999
int e[505][505],sp[505][505];
int main()
{int n,m,d,s,i,j,k,x,y,z,q;scanf("%d%d%d%d",&n,&m,&s,&d);for(i=0; i<n; i++){for(j=0; j<n; j++){if(i==j)  e[i][j]=sp[i][j]=0;else e[i][j]=sp[i][j]=max;}}for(i=0; i<m; i++){scanf("%d%d%d%d",&x,&y,&z,&q);if(e[x][y]>z){e[x][y]=e[y][x]=z;sp[x][y]=sp[y][x]=q;}}for(k=0; k<n; k++){for(i=0; i<n; i++){for(j=0; j<n; j++){if(e[i][j]>e[i][k]+e[k][j]||(e[i][j]==e[i][k]+e[k][j]&&sp[i][j]>sp[i][k]+sp[k][j])){e[i][j]=e[i][k]+e[k][j];sp[i][j]=sp[i][k]+sp[k][j];}}}}printf("%d %d\n",e[s][d],sp[s][d]);return 0;
}

dijkstra:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define max 99999
int e[550][550];
int dis[550];
int sp[550][550];
int dissp[550];int main()
{int i,j,n,m,s,d,x,y,z,a,min,v;int book[550]= {0};scanf("%d%d%d%d",&n,&m,&s,&d);for(i=0; i<n; i++){for(j=0; j<n; j++){if(i==j) e[i][j]=sp[i][j]=0;else e[i][j]=sp[i][j]=max;}}for(i=0; i<m; i++){scanf("%d%d%d%d",&x,&y,&z,&a);if(e[x][y]>z){e[y][x]=e[x][y]=z;sp[y][x]=sp[x][y]=a;}}for(i=0; i<n; i++){dis[i]=e[s][i];dissp[i]=sp[s][i];}book[s]=1;for(i=0; i<n-1; i++){min=max;for(j=0; j<n; j++){if(book[j]==0&&dis[j]<min){min=dis[j];v=j;}}book[v]=1;for(j=0;j<n;j++){if(e[v][j]<max){if(dis[v]>dis[j]+e[v][j]||(dis[v]==dis[j]+e[v][j]&&dissp[v]>dissp[j]+sp[v][j])){dis[v]=dis[j]+e[v][j];dissp[v]=dissp[j]+sp[v][j];}}}}printf("%d %d\n",dis[d],dissp[d]);return 0;
}

7-4 城市间紧急救援 (25分)

https://pintia.cn/problem-sets/1305333141335306240/problems/1305333237913350147

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

输入格式:
输入第一行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N−1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。

第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

输出格式:
第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。

输入样例:
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
输出样例:
2 60
0 1 3

代码参考:https://blog.csdn.net/qq_42623428/article/details/83098065?utm_source=app
五天,我终于把这个题给A了。。。

简洁版:

#include <bits/stdc++.h>
using namespace std;const int mxx = 0x3f3f3f3f;
const int N = 550;
int n, m, s, d;
int mp[N][N], help[N], ds[N], hp[N];
int vis[N] = {0}, nt[N] = {0}, num[N] = {0};int main()
{cin >> n >> m >> s >> d;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)if (i == j)  mp[i][j] = 0;else  mp[i][j] = mxx;for (int i = 0; i < n; i++)cin >> help[i];for (int i = 0; i < m; i++){int x, y, z;cin >> x >> y >> z;if (mp[x][y] > z)  mp[x][y] = mp[y][x] = z;}for (int i = 0; i < n; i++)ds[i] = mp[s][i], hp[i] = help[i], num[i] = 1;vis[s] = 1, nt[s] = -1;for (int i = 0; i < n; i++){int mnn = mxx, v;for (int j = 0; j < n; j++)if (!vis[j] && mnn > ds[j])mnn = ds[j], v = j;vis[v] = 1;for (int j = 0; j < n; j++){if (!vis[j] && mp[v][j]){if (ds[j] > ds[v] + mp[v][j]){ds[j] = ds[v] + mp[v][j];hp[j] = hp[v] + help[j];nt[j] = v;num[j] = num[v];}else if (ds[j] == ds[v] + mp[v][j]){if (hp[j] < hp[v] + help[j])hp[j] = hp[v] + help[j], nt[j] = v;num[j] += num[v];}}}}cout << num[d] << ' ' << hp[d] + help[s] << endl;int t = d;stack<int> st;while (t != -1) st.push(t), t = nt[t]; while (!st.empty()){cout << st.top();st.pop();if (st.empty())  cout << endl;else   cout << ' ';}return 0;
}

注释版:

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define maxx 999999
using namespace std;
int e[550][550],book[550]= {0},dis[550];
//边 是否遍历 最短路径长度
int help[550],helpma[550]={0},path[550]= {0},num[550]={0};
//救援队数量 到达某点时召集的救援队数量 经过的路径 最短路的个数
int main()
{int n,m,s,d,i,j;scanf("%d%d%d%d",&n,&m,&s,&d);for(i=0; i<n; i++){scanf("%d",&help[i]);helpma[i]=help[i];}for(i=0; i<n; i++){for(j=0; j<n; j++){if(i==j)e[i][j]=0;else e[i][j]=maxx;}}for(i=0; i<m; i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);if(e[x][y]>z) e[y][x]=e[x][y]=z;}for(i=0; i<n; i++)dis[i]=e[s][i];int minn,v;num[s]=1;for(i=0; i<n; i++){minn=maxx;for(j=0; j<n; j++){if(dis[j]<minn&&book[j]==0){minn=dis[j];v=j;}}book[v]=1;for(j=0; j<n; j++){if(book[j]==0&&e[v][j]<maxx){if(dis[j]>dis[v]+e[v][j]){num[j]=num[v];dis[j]=dis[v]+e[v][j];helpma[j]=helpma[v]+help[j];path[j]=v;}else if(dis[j]==dis[v]+e[v][j]){num[j]=num[v]+num[j]; // 如果是num[j]=num[v]+1,那么j点只能在v的基础加一个路径数,如果从v到j有两条最短路径,也只能加一个路径数if(helpma[j]<helpma[v]+help[j]){helpma[j]=helpma[v]+help[j];path[j]=v;}}}}}printf("%d %d\n",num[d],helpma[d]);int road[550],t=d;j=0;road[j++]=d; //路径是从后往前找的,因为这个地方w了好几次while(path[t]){road[j++]=path[t];t=path[t];}road[j++]=s;for(i=j-1;i>=0;i--){if(i==j-1) printf("%d",road[i]);else printf(" %d",road[i]);}return 0;
}

天梯赛最短路专题 -- 旅游规划、城市间紧急救援相关推荐

  1. 2020年全国天梯赛赛前个人专题强化赛---C(最短路)

    7-1 垃圾箱分布 (30分) 大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住.所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个 ...

  2. PTA 天梯赛习题集 L2-001 城市间紧急救援

    城市间紧急救援 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当 ...

  3. 5-35 城市间紧急救援 (25分) pat 数据结构

    题目连接 https://pta.patest.cn/pta/test/15/exam/4/question/862 5-35 城市间紧急救援   (25分) 作为一个城市的应急救援队伍的负责人,你有 ...

  4. 城市间紧急救援(25 分)

    这个题目,一开始用数组统计路径个数,在更新最短路的路径个数时总是错误,后来直接从起点回溯了一遍,就可以了, 更新最短路的时候有两个权值因素,一个是路径长度一个是数目,在路径在同一个结点的时候要选择数目 ...

  5. 5-35 城市间紧急救援 (25分)

    5-35 城市间紧急救援 (25分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道 ...

  6. 7-1 城市间紧急救援 (25 分)

    7-1 城市间紧急救援 (25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道 ...

  7. 7-15 城市间紧急救援 (10 分)

    7-15 城市间紧急救援 (10 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速 ...

  8. pta紧急救援java,PTA——城市间紧急救援

    PTA--城市间紧急救援 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在 ...

  9. 7-1 城市间紧急救援

    7-1 城市间紧急救援 题目描述: 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路 ...

最新文章

  1. fragment切换事件
  2. java push_back,将一个结构push_back()一个向量
  3. MS SQL 导入导出 提示 未在本地计算机上注册“Microsoft.ACE.Oledb.12.0”提供程序。(System.Data)...
  4. 【数字信号处理】 第二章、时域中的离散时间信号
  5. active mq topic消费后删除_《我想进大厂》之MQ夺命连环11问
  6. WebSocket知识点总结
  7. 模糊逻辑学习--建立Mamdani系统(GUI)
  8. pg数据库的一些问题
  9. 高压油管matlab,高压油管的压力及流量控制
  10. C语言引用方式调用函数
  11. python监听多个udp端口_尝试实现非阻塞python-udp多端口获取wierd异常
  12. Shiro框架学习笔记、整合Springboot、redis缓存
  13. Unity3d+moba+草丛视野
  14. php 改数字 例如10000变成1万
  15. 【Python】破解摩斯密码
  16. sprintf与snprintf区别
  17. 常见室内观赏植物的管理技术大全
  18. 联通3g上网卡 linux驱动,驱动天空 - 网络设备 - 联通3G上网卡WCDMA
  19. Redis、MongoDB及Memcached的区别,java架构师课程推荐
  20. john破解用户密码和防破解

热门文章

  1. 火狐浏览器新标签页搜索栏不能打字
  2. java实例化出错_实例化servlet类时出错
  3. Bean实例化的三种方式
  4. sql 抛出异常raiserror()
  5. 量化交易 第五课 策略评估指标
  6. JMC3608兼容代替SX1308,SDB628,LP6238,HX3608,MT3608,B628,TC3608,LN3608
  7. 模拟登陆 12306网站
  8. 你问我你喜欢这个世界么
  9. 关于高德地图地理围栏生成后在BroadcastReceiver的onReceive方法中没有接收到消息的问题
  10. 电话簿与vCard的格式转换