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

输入格式:

输入第一行给出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. ps命令查看进程指定项目信息、用户名过长显示UID

    有次一个在使用ps命令时,发现部分用户显示的是用户名,有些用户显示的是UID,那是因为用户名长度超过8位的:也就是说ps命令用户名列默认只能显示8位(含8位)的用户名,超过8位就显示UID,如何让长度 ...

  2. vs报错“以下文件中的行尾不一致,是否将行尾标准化”

    vs报错"以下文件中的行尾不一致,是否将行尾标准化" 分析: 通过读取源文件,发现换行都使用的是"\n"   Windows和Unix不同的标准引起的...即& ...

  3. 【Android】Android之USB

    [转载请注明出处] 首先介绍一个概念:USB Host and Accessory Android通过两种模式支持一系列的USB外围设备和Android USB附件(实现了Android附件协议的硬件 ...

  4. Strand Sort

    Strand sort是思路是这样的,它首先需要一个空的数组用来存放最终的输出结果,给它取个名字叫"有序数组" 然后每次遍历待排数组,得到一个"子有序数组",然 ...

  5. redis 模糊查找keys

    Redis入门教程可参考:超强.超详细Redis数据库入门教程 Redis操作命令可参考:Redis操作命令总结 redis可以通过命令Keys Match来进行键值的模糊匹配,借助StackExch ...

  6. 省队集训 Day3 吴清华

    [题目大意] 给网格图,共有$n * n$个关键节点,横向.纵向距离均为$d$,那么网格总长度和宽度均为$(n+1) * d + 1$,最外围一圈除了四角是终止节点.要求每个关键节点都要通过线连向终止 ...

  7. 【NOIP】提高组2013 转圈游戏

    [算法]快速幂运算 [题解]ans=(m*10^k+x)%n,用快速幂计算10^k即可,复杂度为O(log k). #include<cstdio> long long n,m,k,x,a ...

  8. 【游记】GDOI 2017

    Day 0 学校好大>_<! 酒店好高级>_<! 晚上复习代码的时候很困QAQ,中间和hwh面基.复习到SA的时候因为太久没看忘记板子的意思了又背不下来,于是不看了,相信考了也 ...

  9. 在非ARC工程中使用ARC库

    选中工程->TARGETS->相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了.为对应的库文件添加:-fobjc-arc参数即可 ...

  10. [IOS]Xcode各版本官方下载及百度云盘下载, Mac和IOS及Xcode版本历史

    官方下载, 用开发者账户登录,建议用Safari浏览器下载. 官方下载地址: https://developer.apple.com/xcode/downloads/ 百度云盘下载地址 http:// ...