#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> using namespace std; #define MAX_NUMBER 100000000 int G[510][510]; int current_team[510]; bool visit[510]; int dist[510]; int paths[510]; int max_teams[510]; void dij(int N,int C1, int C2) { int i,j,k; dist[C1] = 0; paths[C1] =1; max_teams[C1] = current_team[C1]; for(i=0;i<N;i++) { int _min = MAX_NUMBER; int u =0; for(j=0;j<N;j++) //选取距离最近点 { if(visit[j]==false && dist[j] < _min) { _min = dist[j]; u = j; } } if(u == C2 || _min== MAX_NUMBER) //已经更新到目标点或者没有路径 { break; } visit[u] = true; for(k=0;k<N;k++) //更新最小距离 { if(visit[k]) //若是已经在集合中,则继续 continue; int temp_dist = dist[u] + G[u][k]; //u是最小距离中间点 if(temp_dist < dist[k]) { dist[k] = temp_dist; paths[k] = paths[u]; //说明目前只有一个路径 max_teams[k] = max_teams[u]+ current_team[k]; } else if(temp_dist == dist[k]) //路径相同,则再比较最大帮助人 { paths[k] += paths[u]; //多路径累加 if(max_teams[u]+current_team[k] > max_teams[k]) max_teams[k] = max_teams[u]+current_team[k]; } } } printf("%d %d\n",paths[C2],max_teams[C2]); } int main() { int N,M,C1,C2; int i,j,k; int temp_i,temp_j; int temp_weight; int min_length; int teams =0; while(scanf("%d %d %d %d",&N,&M,&C1,&C2)!=EOF) { teams =0; for(i =0;i<N;i++) scanf("%d",¤t_team[i]); for(i =0;i<N;i++) { paths[i] = 0; dist[i] = MAX_NUMBER; visit[i] = false; } for(i=0;i<N;i++) for(j=0;j<N;j++) { G[i][j] = MAX_NUMBER; G[j][i] = MAX_NUMBER; } for(i=0;i<M;i++) { scanf("%d %d %d",&temp_i,&temp_j,&temp_weight); G[temp_i][temp_j] = temp_weight; G[temp_j][temp_i] = temp_weight; } dij(N,C1,C2); } return 0; }