L2-001 紧急救援(五香连通图输出最短的路径以及最短路径的条数还有最大收益)

本文主要是介绍L2-001 紧急救援(五香连通图输出最短的路径以及最短路径的条数还有最大收益),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

输入格式:

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

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

输出格式:

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

输入样例1:

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出样例1:

2 60
0 1 3

 

 

 

输入样例2:(该样例并非是最优解唯一,仅仅用作检测最短路径的条数是否正确)

8 15 0 7
10 10 10 10 10 10 10 10
0 1 1
0 2 1
0 3 1
7 4 1
7 5 1
7 6 1
1 4 1
1 5 1
1 6 1
2 4 1
2 5 1
2 6 1
3 4 1
3 5 1 
3 6 1

输出样例2:

9 40
0 1 4 7

 错误代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<set>
using namespace std;
typedef long long ll;
const int N=510;
int p[N][N];
int dist[N];
int dist1[N];
int d[N];
int sum;
int root,mx;
int n,m, s,t1;
int f[N];
bool st[N];
void dfs(int x,int u)
{if(x!=root){dfs(f[x],u+1);}else{cout<<x<<' ';return;}if(u!=1)cout<<x<<' ';elsecout<<x;
}
void dijk()
{memset(dist ,0x3f,sizeof dist);memset(dist1,0,sizeof dist1);dist1[s]=d[s];dist[s]=0;for(int i=1;i<=n;i++){int t=-1;for(int j=0;j<n;j++){if(!st[j]&&(t==-1||(dist[t]>dist[j]))){t=j;}}st[t]=true;for(int j=0;j<n;j++){if(dist[t]+p[t][j]<dist[j]){f[j]=t;if(j==t1&&dist[t]+p[t][j]<mx)//错误点{mx=dist[t]+p[t][j];sum=1;}dist[j]=dist[t]+p[t][j];dist1[j]=dist1[t]+d[j];}else if(dist[t]+p[t][j]==dist[j]){if(j==t1&&mx==dist[j])sum++;//错误点,仅仅只是看最终达到终点//的最短路径的次数决定了最短路径//的数目,忽略了路径上的其他点的可能遍历次数if(dist1[j]<dist1[t]+d[j]){dist1[j]=dist1[t]+d[j];f[j]=t;}}}}
}
int main()
{cin>>n>>m>>s>>t1;for(int i=0;i<n;i++)cin>>d[i];f[s]=s;mx=0x3f3f3f3f;memset(p,0x3f,sizeof p);while(m--){int a,b,c;cin>>a>>b>>c;p[a][b]=min(p[a][b],c);p[b][a]=p[a][b];}dijk();cout<<sum<<' '<<dist1[t1]<<endl;dfs(t1,1);return 0;
}

样例2下的错误输出:

3 40
0 1 4 7

正确代码 :

思路(在更新最短距离时用一个数组记录到达一个节点的最短路径个数,如果最短距离被更新,则个数由中间点t的个数值决定,如果最短距离相同,则个数由该点和中间点共同决定)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<set>
using namespace std;
typedef long long ll;
const int N=510;
int p[N][N];
int dist[N];
int dist1[N];
int d[N];
int sum;
int root,mx;
int n,m, s,t1;
int f[N];
int cnt[N];
bool st[N];
void dfs(int x,int u)
{if(x!=root){dfs(f[x],u+1);}else{cout<<x<<' ';return;}if(u!=1)cout<<x<<' ';elsecout<<x;
}
void dijk()
{memset(dist ,0x3f,sizeof dist);memset(cnt,0,sizeof cnt);cnt[s]=1;dist1[s]=d[s];dist[s]=0;for(int i=1;i<=n;i++){int t=-1;for(int j=0;j<n;j++){if(!st[j]&&(t==-1||dist[t]>dist[j]))t=j;}st[t]=true;for(int j=0;j<n;j++){if(dist[t]+p[t][j]<dist[j]){f[j]=t;dist[j]=dist[t]+p[t][j];dist1[j]=dist1[t]+d[j];cnt[j]=cnt[t];}else if (dist[j]==dist[t]+p[t][j]){cnt[j]=cnt[t]+cnt[j];if(dist1[j]<dist1[t]+d[j]){f[j]=t;dist1[j]=dist1[t]+d[j];}}}}
}
int main()
{cin>>n>>m>>s>>t1;for(int i=0;i<n;i++)cin>>d[i];f[s]=s;mx=0x3f3f3f3f;memset(p,0x3f,sizeof p);while(m--){int a,b,c;cin>>a>>b>>c;p[a][b]=min(p[a][b],c);p[b][a]=p[a][b];}dijk();cout<<cnt[t1]<<' '<<dist1[t1]<<endl;dfs(t1,1);return 0;
}

这篇关于L2-001 紧急救援(五香连通图输出最短的路径以及最短路径的条数还有最大收益)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/488100

相关文章

随想录 Day 69 并查集 107. 寻找存在的路径

随想录 Day 69 并查集 107. 寻找存在的路径 理论基础 int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好vector<int> father = vector<int> (n, 0); // C++里的一种数组结构// 并查集初始化void init() {for (int i = 0; i < n; ++i) {father[i] = i;}

SQL Server中,用Restore DataBase把数据库还原到指定的路径

restore database 数据库名 from disk='备份文件路径' with move '数据库文件名' to '数据库文件放置路径', move '日志文件名' to '日志文件存放置路径' Go 如: restore database EaseWe from disk='H:\EaseWe.bak' with move 'Ease

LeetCode--214 最短回文串

题目 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 示例 示例 1:输入: "aacecaaa"输出: "aaacecaaa"示例 2:输入: "abcd"输出: "dcbabcd" 思路: 我们需要添加多少个字符与给定字符串的前缀子串回文的长度有关. 也就是说去掉其前缀的回文子串,我们只需要补充剩下的子串的逆序

神经网络第三篇:输出层及softmax函数

在上一篇专题中,我们以三层神经网络的实现为例,介绍了如何利用Python和Numpy编程实现神经网络的计算。其中,中间(隐藏)层和输出层的激活函数分别选择了 sigmoid函数和恒等函数。此刻,我们心中不难发问:为什么要花一个专题来介绍输出层及其激活函数?它和中间层又有什么区别?softmax函数何来何去?下面我们带着这些疑问进入本专题的知识点: 1 输出层概述 2 回归问题及恒等函数 3

C# 命名管道中客户端访问服务器时,出现“对路径的访问被拒绝”

先还原一下我出现错误的情景:我用C#控制台写了一个命名管道服务器,然后用ASP.NET写了一个客户端访问服务器,运行之后出现了下面的错误: 原因:服务器端的访问权限不够,所以是服务器端的问题,需要增加访问权限。(网上很多都说是文件夹的权限不够,情况不同,不适用于我这种情况) 解决办法: (1)在服务器端相应地方添加以下代码。 PipeSecurity pse = new PipeSec

代码随想录算法训练营第三十九天|62.不同路径 63. 不同路径 II 343.整数拆分 96.不同的二叉搜索树

LeetCode 62.不同路径 题目链接:62.不同路径 踩坑:二维的vector数组需要初始化,否则会报错访问空指针 思路: 确定动态数组的含义:dp[i][j]:到达(i,j)有多少条路经递推公式:dp[i][j] = dp[i-1][j] + dp[i][j-1]初始化动态数组:dp[0][0] = 1遍历顺序:从左到右,从上到下 代码: class Solution {pu

关于修改计算机的处理器数和最大内存数的问题

问题描述: 刚开始本来是想让计算机的运行速度运行的快点,于是在网上搜索如何让计算机的运行速度更快,找到了一种关于修改计算机内存数和计算机的处理核数可以让计算机运行的更快。 遇到问题: 当我通过命令msconfig →引导→高级选项→勾选了处理器数和最大内存数,然后重启,结构整个计算机都卡的要死,于是记录下来。网上的答案有时候真的是很不负责任,也有可能是自己技术不到位。 结果:取消处理器和内

poj 3160 Father Christmas flymouse 强连通+dp

首先我们可以确定的是,对于val值小于0的节点都变成0.   假设一个集合内2个房间都能任意到达,那么我就可以吧集合内的所有点的价值都取到,并且可以达到任一点。实际上集合内的每个点是相同的,这样的集合就是一个强连通分量。 那么我们就可以用tarjin算法进行强连通缩点, 最后形成一个dag的图。在dag的图上面进行dp。可以先用拓扑排序后dp。或者建反响边记忆化搜索 。 VIEW

C语言中的字符输入/输出和验证输入

在C语言中,字符输入/输出功能允许程序与用户进行交互,读取用户的输入信息并展示输出结果。同时,验证输入的作用在于确保用户输入的数据符合预期,以提高程序的稳定性和可靠性,防止无效输入引发的错误或异常行为,从而提供更好的用户体验。 基础概念 输入(Input):指的是向程序填充数据的过程,通常来源于用户输入、文件读取或其他外部数据源。 输出(Output):指的是将数据显示在屏幕上、打印机上或