题意要求出最短路径数目和最小花费。经典的Dijkstral算法变形。
// 1003. Emergency.cpp: 主项目文件。
#include <cstdio>
#include <cstring>
const int N=501;
const int INT_MAX=1<<30;
int map[N][N];
bool used[N];
int people[N];
int dist[N],resource[N],paths[N];
int n,m,start,end;
void dijsktral(){
if(start==end){
printf("1 %d\n",people[start]);
return;
}
memset(used,0,sizeof(used));
for(int i=0;i<n;i++){
dist[i]=map[start][i];
if(map[start][i]!=INT_MAX){
resource[i]=people[start]+people[i];
paths[i]=1;
}
else{
resource[i]=0;
paths[i]=0;
}
}
resource[start]=people[start];
used[start]=true;
for(int i=1;i<n;i++){
int min=INT_MAX,minf=-1;
for(int j=0;j<n;j++){
if(!used[j]&&dist[j]<min){
min=dist[j];
minf=j;
}
}
used[minf]=true;
if(minf==end)
break;
for(int j=0;j<n;j++){
if(!used[j]){
int distTemp=dist[minf]+map[minf][j],
resourceTemp=resource[minf]+people[j];
if(distTemp<dist[j]){
dist[j]=distTemp;
paths[j]=paths[minf];
resource[j]=resourceTemp;
}
else if(distTemp==dist[j]){
paths[j]=paths[minf]+paths[j];
if(resourceTemp>resource[j])
resource[j]=resourceTemp;
}
}
}
}
printf("%d %d\n",paths[end],resource[end]);
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&start,&end)){
for(int i=0;i<n;i++)
scanf("%d",people+i);
for(int i=0;i<n;i++)
for(int j=i;j<n;j++)
map[i][j]=map[j][i]=INT_MAX;
for(int i=0;i<m;i++){
int from,to,dd;
scanf("%d%d%d",&from,&to,&dd);
if(map[from][to]>dd)
map[from][to]=map[to][from]=dd;
}
dijsktral();
}
return 0;
}