As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) - the number of cities (and the cities are numbered from 0 to N-1), M - the number of roads, C1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output

2 4
 #include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int G[][], teams[], dst[], visit[] = {}, pathNum[] = {}, teamSum[] = {};
int N, M, C1, C2;
const int INF = ;
void dijkstra(int s){
pathNum[s] = ;
for(int i = ; i < N; i++){
dst[i] = INF;
}
dst[s] = ;
teamSum[s] = teams[s];
for(int i = ; i < N; i++){
int u = -, minlen = INF;
for(int j = ; j < N; j++){
if(visit[j] == && dst[j] < minlen){
minlen = dst[j];
u = j;
}
}
if(u == -)
return;
else visit[u] = ;
for(int j = ; j < N; j++){
if(visit[j] == && G[u][j] != INF && dst[u] + G[u][j] < dst[j]){
dst[j] = dst[u] + G[u][j];
pathNum[j] = pathNum[u];
teamSum[j] = teamSum[u] + teams[j];
}else if(visit[j] == && G[u][j] != INF && dst[u] + G[u][j] == dst[j] && teamSum[u] + teams[j] > teamSum[j]){
dst[j] = dst[u] + G[u][j];
pathNum[j] += pathNum[u];
teamSum[j] = teamSum[u] + teams[j];
}else if(visit[j] == && G[u][j] != INF && dst[u] + G[u][j] == dst[j] && teamSum[u] + teams[j] <= teamSum[j]){
dst[j] = dst[u] + G[u][j];
pathNum[j] += pathNum[u];
}
}
}
}
int main(){
scanf("%d%d%d%d", &N, &M, &C1, &C2);
int temp1, temp2, temp3;
for(int i = ; i < N; i++){
scanf("%d", &teams[i]);
}
fill(G[], G[] + *, INF);
for(int i = ; i < M; i++){
scanf("%d%d%d", &temp1, &temp2, &temp3);
G[temp1][temp2] = G[temp2][temp1] = temp3;
}
dijkstra(C1);
printf("%d %d", pathNum[C2], teamSum[C2]);
cin >> N;
return ;
}

总结:

1、迪杰斯特拉求最短路径,并计算最短路径的条数。如果有多条最短路,计算出他们中的最大点权之和。

2、迪杰斯特拉伪代码:

int visit[], G[][], dst[], pathNum[], v[], w[];
void dijkstra(int s){
初始化:visit表示已经最优的点,初始全为0.
G存储图,初始全为INF
dst存储到源点的最短距离,初始dst[s]为0,其它为INF
pathNum存储到源点的最短路条数,初始pathNum[s]为1,其它全为0
v表示从源点一路累加的点权之和(应还有一个记录点权的数组),初始v[s]为自身的点权,其它全为0
w表示从源点一路累加的边权之和,初始只有w[s]为0,其它全为INF
for(int i = ; i < N; i++){//循环N次,每次能找到一个
int u = -;
选择一个未被最优化的且dst最短的节点为u
将其visit设为1
for(int j = ; j < N; j++){
if(visit[j] == && G[u][j] != INF){
if(dst[u] + G[u][j] < dst[j]){
dst[j] = dst[u] + G[u][j];
pathNum[j] = pathNum[u];
}else if(dst[u] + G[u][j] == dst[j]){
pathNum[j] = pathNum[j] + pathNum[u];
}
}
}
}
}

在第一标尺(最短距离)相等的情况下,第二标尺:

边权:当距离更优时,更新dst和w;当距离相等时且第二标尺更优时,更新第二标尺w。

点权:同边权

最短路径条数:当距离更优时,pathNum[ j ]继承pathNum[ u ]。当距离相等时, pathNum[ j ]累加pathNum[ u ]。

3、dijkstra + DFS:仅仅用dijkstra专心求最短路,在过程中记录前驱节点。使用 vector<int> pre[100],当 dst[u] + G[u][j] < dst[j] 时,清空pre[ j ],并将u加入其中。当 dst[u] + G[u][j] == dst[j] 时,仅仅把u加入pre[ j ]。最终得到一棵以终点C2为根,以源点C1为叶节点的树。可以使用DFS,与一个vector<int> temp,得到一条完整路径后再计算各种标尺。

4、初始化   const int INF = 100000000;       fill(G[0], G[0] + 501*501, INF);

A1003. Emergency的更多相关文章

  1. PAT A1003 Emergency 题解

    PAT A1003 Emergency PAT A1003 Emergency 题目简述: 原题为英文题目,所以在这里简述一下题意: 给定n个点和m条无向路以及起点.终点 下面一行n个数,第i个数表示 ...

  2. PAT_A1003#Emergency

    Source: PAT A1003 Emergency (25 分) Description: As an emergency rescue team leader of a city, you ar ...

  3. PTA A1003&A1004

    第二天 A1003 Emergency (25 分) 题目内容 As an emergency rescue team leader of a city, you are given a specia ...

  4. PAT (Advanced Level) Practice(更新中)

    Source: PAT (Advanced Level) Practice Reference: [1]胡凡,曾磊.算法笔记[M].机械工业出版社.2016.7 Outline: 基础数据结构: 线性 ...

  5. 图的最短路径Dijkstra

    #include <stdio.h> #include <string.h> #include <vector> #include <queue> #i ...

  6. PAT甲级题解分类byZlc

    专题一  字符串处理 A1001 Format(20) #include<cstdio> int main () { ]; int a,b,sum; scanf ("%d %d& ...

  7. 1003 Emergency (25 分)

    1003 Emergency (25 分) As an emergency rescue team leader of a city, you are given a special map of y ...

  8. 1003. Emergency (25)

    As an emergency rescue team leader of a city, you are given a special map of your country. The map s ...

  9. Emergency(山东省第一届ACM省赛)

    Emergency Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Kudo’s real name is not Kudo. H ...

随机推荐

  1. hive子查询

    如果集合中含有空值,不能使用not in的语法指令:但是可以使用in

  2. linux不同终端的操作是如何在messages日志中区分的

    今天在定位一个问题时,查看message日志,需要知道message日志中的记录分别是哪个Xterm终端操作的.比较了半天才发现原来日志中可以通过pts来进行区分.如下所示: --12T15:::|n ...

  3. 表单中input name属性有无[]的区别

    1 input数组 如下一个表单: <input type="text" name="username[]" value="Jason" ...

  4. Lodop如何打印直线

    Lodop打印设计提供了可视化设计,生成代码的方便,在打印设计界面上,选择添加打印项的时候,可以看到没有添加直线选项,可添加斜线,然后把添加的斜线调整成直线:线宽=高 -----水平直线线宽=宽--- ...

  5. vue 使用技巧总结 18.11

    前言: 在大概学完 vue 整体框架后,有幸接触到花裤衩大神写的 vue-elementUI-admin 模板框架,把这个模板框架当作 demo,跟着 code 一遍,最大的收获是在以逻辑简单的模板熟 ...

  6. 前端es6基础语法

    1.let.const.var var是声明全局的变量,作用域是全局,const是声明全局的常量,不能修改,而let是块级变量只在当前声明的作用域中生效: { var a = 10; let b = ...

  7. POJ3468/splay树/成段更新

    板子题,正在努力看懂板子.. http://blog.csdn.net/acm_cxlove/article/details/7815019 http://www.cnblogs.com/kuangb ...

  8. 【XSY2669】归并排序 树状数组 简单组合数学

    题目描述 有一个长度为\(n\)的排列\(n=2^k\),你要把这个数组归并排序.但是在长度为\(2\)的时候有\(\frac{1}{2}\)的概率会把两个数交换(就是有\(\frac{1}{2}\) ...

  9. 卢卡斯定理&扩展卢卡斯定理

    卢卡斯定理 求\(C_m^n~mod~p\) 设\(m={a_0}^{p_0}+{a_1}^{p_1}+\cdots+{a_k}^{p_k},n={b_0}^{p_0}+{b_1}^{p_1}+\cd ...

  10. 【cf789B】Masha and geometric depression(分类讨论/暴力)

    B. Masha and geometric depression 题意 在黑板上写数列,首项是b,公比是q,超过l时就停止不写.给定m个数,遇到后跳过不写.问一共写多少个数,如果无穷个输出inf. ...