题目:求从c1到c2最短路径的数量,以及最短路径中的最多的救援队数量。
思路:使用dijkstra
#include<iostream>
#define MAXN 510
using namespace std;
const int inf=898989;
int rescue[MAXN],roadNum[MAXN],roadMin[MAXN],vis[MAXN],rescueMAX[MAXN];//救援队,道路数量,
int road[MAXN][MAXN];
//N表示城市数量(城市编号从 0 到 N−1),M表示道路数量,C1表示你当前所在的城市编号,C2表示发出紧急求援信息的城市编号。
int n,m,c1,c2;
void dijkstra(int start){
roadMin[start]=0;
roadNum[start]=1;
rescueMAX[start]=rescue[start];
int u=start;
for(int i=0;i<n;i++){
int minL=inf,v=-1;
for(int j=0;j<n;j++){
if(!vis[j] && roadMin[j]<minL){
minL= roadMin[j];
v=j;
}
}
if(v==-1)break;
// printf("test:%d roadMin[%d]=%d\n",v,v,roadMin[v]);
vis[v]=1;
//更新
for(int j=0;j<n;j++){
if(!vis[j] && roadMin[v] + road[v][j] < roadMin[j]){//
roadMin[j]= roadMin[v]+road[v][j];
rescueMAX[j] = rescueMAX[v] + rescue[j];
roadNum[j] = roadNum[v];
// printf("roadNum[%d]=%d\n",j,roadNum[j]);
}
else if(!vis[j]&&roadMin[v]+road[v][j]==roadMin[j]){
roadNum[j] += roadNum[v];
// printf("roadNum[%d]=%d\n",j,roadNum[j]);
if(rescueMAX[v]+rescue[j]>rescueMAX[j]){
rescueMAX[j] = rescueMAX[v]+rescue[j];
}
}
}
}
}
int main(){
cin>>n>>m>>c1>>c2;
for(int i=0;i<n;i++){
cin>>rescue[i];
}
//初始化
for(int i=0;i<n;i++){
for(int j=0;j<n;j++) if(i!=j) road[i][j]=inf;
}
for(int i=0;i<n;i++) roadMin[i]=inf;
for(int i=0;i<m;i++){
int a,b,l;
cin>>a>>b>>l;
road[a][b]=road[b][a]=l;
}
dijkstra(c1);
//输出结果
cout<<roadNum[c2]<<" "<<rescueMAX[c2];
return 0;
}