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

输入格式:

输入第一行给出4个正整数N、M、S、D,其中N(2)是城市的个数,顺便假设城市的编号为0 ~ (;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

这道题我用带pair的优先队列的迪杰斯特拉跑,保存所有满足条件的路径,然后dfs找出所有路径并找出每条路径的人数,然后输出来最优的。但是怎么都过不去第二个样例,百度了一下,发现有人和我一样的问题,怎么改都过不了,最后死心了,换了一个就过了。。。

贴一下我错误的代码,谁来拯救一下我。。。

错误代码(过不了第二个样例):

 //紧急救援-wa2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int inf=0x3f3f3f3f;
const int maxn=1e6+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m,st,ed;
int cnt=,head[maxn<<],p[maxn];
bool vist[maxn];
int dis[maxn],val[maxn];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
vector<int> path[maxn]; struct node{
int v,nex;
int w,num;
}edge[maxn<<]; void add(int u,int v,ll w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt++;
} void dijkstra(int s)
{
dis[s]=;//到自己的最短距离直接设为0
// sum[s]=val[s];
q.push(make_pair(,s));
while(!q.empty()){//队列非空
int u=q.top().second;q.pop();
if(vist[u]) continue;
vist[u]=true;
if(u==ed+) break;
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v;
// ll s=val[v];
int w=edge[i].w;
if(vist[v]) continue;
if(dis[v]>dis[u]+w){//满足条件更新距离
dis[v]=dis[u]+w;
// sum[v]=sum[u]+s;
// p[v]=u;//保存路径
path[v].clear();
path[v].push_back(u);
q.push(make_pair(dis[v],v));//把更新完的值压入队列
}
else if(dis[v]==dis[u]+w){
path[v].push_back(u);
q.push(make_pair(dis[v],v));
}
}
}
} vector<int> minPath[maxn];
int sum=;
int number=; void dfs(int s)
{
sum+=val[s];
minPath[number].push_back(s);
if(s==st+){
minPath[number].push_back(sum);
number++;
minPath[number].push_back(ed+);
sum=val[ed+];
}
for(int i=;i<path[s].size();i++){
dfs(path[s][i]);
}
} int main()
{
ios;
// memset(head,-1,sizeof(head));//初始化数组
// memset(vist,false,sizeof(vist));
// memset(dis,inf,sizeof(dis));
cin>>n>>m>>st>>ed;
for(int i=;i<*n+;i++){
head[i]=-;
vist[i]=false;
dis[i]=inf;
}
for(int i=;i<=n;i++)
cin>>val[i];
for(int i=;i<=m;i++){
int u,v;ll w;
cin>>u>>v>>w;
add(u+,v+,w);
add(v+,u+,w);//无向图相互可达 有向图一次就好
}
dijkstra(st+);
int i=ed+;
// ans.push_back(ed+1);
// while(1){
// i=p[i];
// ans.push_back(i);
// if(i==st+1) break;
// }
// cout<<ans.size()<<endl;
// for(int i=(int)ans.size()-1;i>=0;i--)
// cout<<ans[i]-1<<" ";
// cout<<endl;
dfs(ed+);
int pos;
int maxx=-inf;
for(int i=;i<number;i++){
int cnt=minPath[i][minPath[i].size()-];
// cout<<cnt<<endl;
if(maxx<cnt){
maxx=cnt;
pos=i;
}
}
cout<<number-<<" "<<maxx<<endl;
int len=minPath[pos].size();
// cout<<len<<endl;
for(int i=len--;i>;i--)
cout<<minPath[pos][i]-<<" ";
cout<<minPath[pos][]-<<endl;
// cout<<dis[ed+1]<<endl;
// cout<<sum[ed+1]<<endl;
return ;
}

换了一个思路,代码短一些。

正确的代码:

 //again
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e2+;
const int maxm=;
const int inf=0x3f3f3f3f;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); struct Edge{
int v,w; Edge(int v1=,int w1=){
v=v1,w=w1;
} friend bool operator <(Edge a,Edge b){
return a.w>b.w;
} }; int n,m,s,d;
bool vis[maxn];
int dis[maxn],pnum[maxn],rnum[maxn],num[maxn],pre[maxn];//pnum为人数,rnum为路径,num为各城市的人,pre为保存前继节点
vector<Edge> e[maxn];
priority_queue<Edge> pq; void dijkstra()
{
memset(dis,inf,sizeof(dis));
dis[s]=,rnum[s]=,pnum[s]=num[s],pre[s]=-;
pq.push(Edge(s,));
while(!pq.empty()){
int u=pq.top().v;
pq.pop();
if(vis[u]) continue;
vis[u]=true;
if(u==d) break;
for(int i=;i<e[u].size();i++){
int v=e[u][i].v,w=e[u][i].w;
if(!vis[v]){
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
rnum[v]=rnum[u];
pre[v]=u;
pnum[v]=pnum[u]+num[v];
pq.push(Edge(v,dis[v]));
}
else if(dis[u]+w==dis[v]){
rnum[v]+=rnum[u];//上一条的都加进来
if(pnum[u]+num[v]>pnum[v]){//如果有更大的值,就进行更新
pnum[v]=pnum[u]+num[v];
pre[v]=u;
}
}
}
}
}
} stack<int> ans; int main(){
ios;
cin>>n>>m>>s>>d;
for(int i=;i<n;i++)
cin>>num[i];
for(int i=;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
e[u].push_back(Edge(v,w));
e[v].push_back(Edge(u,w));
}
dijkstra();
cout<<rnum[d]<<" "<<pnum[d]<<endl;
while(d!=-){
ans.push(d);
d=pre[d];
}
while(ans.size()>){
cout<<ans.top()<<" ";
ans.pop();
}
cout<<ans.top();
return ;
}

参考:

利用Dijkstra算法实现记录每个结点的所有最短路径

团体程序设计天梯赛-练习集-L2-001 紧急救援(dij最短路)

PTA L2-001 紧急救援-最短路(Dijkstra)多条最短路找最优解并输出路径 团体程序设计天梯赛-练习集的更多相关文章

  1. 团体程序设计天梯赛-练习集L2-001. 紧急救援(dijkstra)

    L2-001. 紧急救援 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国 ...

  2. PTA L2-002 链表去重 团体程序设计天梯赛-练习集

    L2-002 链表去重(25 分)   给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉.即对每个键值 K,只有第一个绝对值等于 K 的结点被保留.同时,所有被删除的结点须被保存在另 ...

  3. PTA L2-023 图着色问题-前向星建图 团体程序设计天梯赛-练习集

    L2-023 图着色问题 (25 分)   图着色问题是一个著名的NP完全问题.给定无向图,,问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解 ...

  4. PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集

    L2-004 这是二叉搜索树吗? (25 分)   一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结 ...

  5. PTA L2-006 树的遍历-二叉树的后序遍历+中序遍历,输出层序遍历 团体程序设计天梯赛-练习集

    L2-006 树的遍历(25 分)   给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤),是二叉树中结点的 ...

  6. PTA L1-020 帅到没朋友 团体程序设计天梯赛-练习集

    L1-020 帅到没朋友(20 分)   当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友.本题就要求你找出那些帅到没有朋友的人. 输入格式: 输入第一行给出一个正整数N(≤),是已 ...

  7. 团体程序设计天梯赛-练习集 L2-001 紧急救援 (25 分)

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

  8. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

  9. 团体程序设计天梯赛L2-001 紧急救援 2017-03-22 17:25 93人阅读 评论(0) 收藏

    L2-001. 紧急救援 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国 ...

随机推荐

  1. lnmp 环境搭建

    3.安装 lnmp : wget http://soft.vpser.net/lnmp/lnmp1.3-full.tar.gz tar -zxvf lnmp1.3-full.tar.gz cd lnm ...

  2. 耗子学Python了(1)___Python环境配置

    一:写在开始的开始 最近我们团对的老大问我想看什么书,我让老大买了一本<Python 3面向对象编程>,所以在看的时候边敲边实践,决定在自己电脑配置下相应的环境,然后开始Python的学习 ...

  3. 51nod 1873 高精度计算

    JAVA BigDecimal import java.util.*; import java.math.*; public class Main { public static void main( ...

  4. (转) jsp学习笔记

    fromhttp://www.cnblogs.com/tao975/p/4445070.html 什么是JSP JSP的优势 JSP的劣势 JSP与PHP的比较 JSP工作原理 JSP的九大内置对象 ...

  5. 【20161109】noip模拟赛

    1.Game [题目描述] 明明和亮亮在玩一个游戏.桌面上一行有n个格子,一些格子中放着棋子.明明和亮亮轮流选择如下方式中的一种移动棋子(图示中o表示棋子,*表示空着的格子): 1) 当一枚棋子的右边 ...

  6. Creating a new dynamic form project, business modeling.

    The domain logic is like there are a bunch of objects, as well as a lot of configurations, according ...

  7. POJ 3061 Subsequence ( 尺取法)

    题目链接 Description A sequence of N positive integers (10 < N < 100 000), each of them less than ...

  8. 安装FFMpeg CentOS 7

    https://linuxadmin.io/install-ffmpeg-on-centos-7/

  9. 【Python学习笔记】使用Python计算皮尔逊相关系数

    源代码不记得是哪里获取的了,侵删.此处博客仅作为自己笔记学习. def multipl(a,b): sumofab=0.0 for i in range(len(a)): temp=a[i]*b[i] ...

  10. LeetCode 19 Valid Parentheses

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...