题意要求出最短路径数目和最小花费。经典的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; }