#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int g[510][510];
int num[510];
int dist[510];
int st[510];
//st确定的顺序不一定是最短路径的顺序,二者没关系
int value[510];//到每个点最短路救援队伍的数量
int cnt[510];//到每个点最短路的数目
int pre[510];//父节点
int main() {
int n, m, s, d;
cin >> n >> m >> s >> d;
memset(dist, 0x3f, sizeof dist);
memset(g, 0x3f, sizeof g);
memset(pre, -1, sizeof pre);
for (int i = 0; i < n; i++) {
cin >> num[i];
}
for (int i = 0; i < m; i++) {
int c1, c2, w;
cin >> c1 >> c2 >> w;
g[c1][c2] = w;
g[c2][c1] = w;
}
dist[s] = 0;
int t = -1;
value[s] = num[s];
cnt[s] = 1;
// st[s] = 1;
for (int j = 0; j < n; j++) {
int tmp = 0;
t = -1;
for (int i = 0; i < n; i++) {
if (!st[i] && (t == -1 || dist[i] < t)) {
t = dist[i];
tmp = i;
}
}
st[tmp] = 1;
for (int i = 0; i < n; i++) {
if (dist[i] > dist[tmp] + g[tmp][i]) {//如果有更短路径
dist[i] = dist[tmp] + g[tmp][i];
value[i] = value[tmp] + num[i];
pre[i] = tmp;
cnt[i] = cnt[tmp];
}
else if ((dist[i] == dist[tmp] + g[tmp][i]) && (tmp != i)) {//如果与最短路长度相等
cnt[i] += cnt[tmp];
if (value[i] < value[tmp] + num[i]) {
value[i] = value[tmp] + num[i];
pre[i] = tmp;
}
}
}
}
cout << cnt[d] << ' ' << value[d] << endl;
vector<int> path;
path.push_back(d);
while (pre[d] != -1) {
path.push_back(pre[d]);
d = pre[d];
}
reverse(path.begin(), path.end());
for (auto iter = path.begin(); iter != path.end() - 1; iter++)
cout << *iter << ' ';
cout << path.back();
}
/*本题出现的问题
1.数组初始化,g[][]起初没有初始化,应该初始化两点距离距离为正无穷
2.无向图要存两个方向的边
3.cnt[i] += cnt[tmp]; 思路要明晰,不是加一是把到tmp的最短路数都加上
4.if elseif 使用时一定注意第二个用if 还是 else if
5.总体逻辑要理清,模板题
*/