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

输入格式:

输入第一行给出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
 
 
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <utility>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cmath>
typedef long long ll;
#define lowbit(x) (x&(-x))
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
#define pi acos(-1)
#define P pair<ll,ll>
int n,m,s,d;
const int N = 1e3+;
int pre[N],f[N][N],val[N],sval[N],dis[N],num[N];
//pre[i]:i前面的点
//sval[i]:到i时的所有最短路径里可以召集的最多的救援队数量
//dis[i]:s 到i 的最短距离
//num[i]:到i的最短路径有几条
int u,v,w;
const int inf = 0x3f3f3f3f;
stack<int>se;
bool vis[N];
void init()
{
for(int i =;i<N;i++)
{
for(int j=;j<N;j++)
{
f[i][j]=(i==j?:inf);
}
dis[i] = inf;
pre[i]=-;
vis[i] = ;
sval[i]=val[i];//易忘记
}
}
void dijk()
{
dis[s]=;
num[s]=;//最重要的。
for(int i =;i<n-;i++)
{
int maxx,min_num;
maxx=inf;
for(int j=;j<n;j++)
{
if(!vis[j]){
if(maxx>dis[j]){
maxx=dis[j];
min_num=j;
}
}
}
vis[min_num]=;
for(int k=;k<n;k++){
if(!vis[k]){ if(dis[k]>dis[min_num]+f[min_num][k]){
dis[k]=dis[min_num]+f[min_num][k];
sval[k]=sval[min_num]+val[k];
pre[k]=min_num;
num[k]=num[min_num];
}
else if(dis[k]==dis[min_num]+f[min_num][k]){
num[k]+=num[min_num];
if(sval[k]<sval[min_num]+val[k]){
sval[k]=max(sval[k],sval[min_num]+val[k]);
pre[k]=min_num; //这里要改变前面的点因为最优路径只有一条
}
}
}
}
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&d);
for(int i =;i<n;i++) scanf("%d",&val[i]);
init();//一定写在输入val[]之后
for(int i =;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
f[u][v]=f[v][u]=w;
}
dijk();
printf("%d %d\n",num[d],sval[d]);
int i=d;
se.push(i);
while(pre[i]!=-){
i=pre[i];
se.push(i);
}
while(!se.empty()){
int u =se.top();
if(u==d) break;
se.pop();
printf("%d ",u);
}
printf("%d\n",d);
return ;
}

最新文章

  1. Hadoop伪分布式集群环境搭建
  2. SPI试验---verilog(实用单通模式)
  3. Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-1
  4. Selenium终极自动化测试环境搭建(一) Selenium+Eclipse+Junit+TestNG
  5. Charles Proxy v4.1.4 免费注册激活方法
  6. centos7.0下的 systemctl 用法
  7. bzoj3277-串
  8. JAVA进阶6
  9. HDU 3533 Escape(大逃亡)
  10. HBase数据模型
  11. centos 7 linux 安装与卸载 tomcat 7
  12. Docker部署运行springboot项目,并使用Dockerfile制作镜像
  13. HTML(四)
  14. poj 3304 Segments 线段与直线相交
  15. JS如何防止事件冒泡
  16. php apache
  17. Spring RedisTemplate操作-xml配置(1)
  18. 如何调整Linux内核启动中的驱动初始化顺序-驱动加载优先级
  19. ios8 xcode6 下的启动界面设置和图标设置
  20. 【BZOJ4195】[Noi2015]程序自动分析 并查集

热门文章

  1. Laravel项目的结构文章
  2. 【踩坑】socket.io服务器不能访问
  3. 【Java】深入理解Java中的spi机制
  4. 用简单的方法学习ES6
  5. Android学习笔记1——Android开发环境配置
  6. jQuery_1_基础核心
  7. IOS 某个控件出不来原因(经验分享)
  8. Processing入门指南
  9. 5分钟了解Java 12 八大新特性
  10. python_30_购物车复习