市の緊急救助チームのヘッドとして、あなたは国の特別なマップを持っています。ロードマップに表示するには、都市と都市との接続のいくつかのより急速な分散を有します。そして、二つの都市の高速道路の長さを結ぶ各都市ごとに救助隊の数は、地図上にマークされています。他の都市はあなたに緊急電話を持っていますが、あなたの使命は、多くの救助隊として召集するための方法に沿って、同時に、できるだけ早く事件に駆けつけレスキューチームをリードすることです。
入力フォーマット:
最初の行の入力は、4つの正の整数N(2≤N≤500)は都市の数であるN、M、S、Dを与え、都市は方法を想定0〜(N-1)の番号、Mは高速でありますいくつかの道路; Sは、番号出発都市のポイントであり、Dは、都市の宛先の数です。
2行目は、数字間のスペースで区切られた都市のi番目のI救助チームの数であるN、整数陽性を与えます。その後のM行の各行は、すなわち、情報の高速な方法を提供し、中間スペースで区切られた2、高速道路の1都市、都市の長さを、数値は500以下の整数です。実行可能な最適解ユニークな救助を確保するために入力。
出力フォーマット:
出力の最短パス最初の行及び招集できる救助隊の最大数の数。2行目は、市内番号を介してDからSパスに出力されます。スペースで区切られた数字の間には、出力の最後には、余分なスペースを持つことができません。
サンプル入力:
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
出力例:
2 60
0 1 3
より観光計画道路より複雑なトピックは、その質問はまた、同じ長さの最短経路の数を記録する必要が最短パス、最小コスト、およびこの質問のパスを記録する必要の長さをカウントしますが、必要があること。
最初に私は、パスの数は、出力ポイントを必要とすること、質問を読み違え...
使用パス[i]を表すI予備パス、pathcnt [i]を表し、S iからの最短経路の数、RES [i]はiは救助チームにsから招集数を表します。
参考:データ構造とアルゴリズムタイトルセット(中国語) - 7-35都市の緊急時間(25ポイント)
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<list>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
#define N 550
#define INF1 0x3f3f3f3f
#define INF2 0xc0c0c0c0
int n,m,s,d;
int dis[N],res[N],pathcnt[N],path[N],vis[N],edge[N][N],num[N];
void dijkstra(){
for(int i=0;i<n;i++) dis[i] = edge[s][i];
int e = s;path[s] = -1;dis[e] = 0;pathcnt[e]=1;
while(e!=d){
vis[e] = 1;
for(int j=0;j<n;j++){
if(!vis[j]){
if(dis[j]>dis[e]+edge[e][j]){
dis[j]=dis[e]+edge[e][j];
res[j] = num[j] + res[e];
pathcnt[j] = pathcnt[e];
path[j] = e;
}
else if(dis[j]==dis[e]+edge[e][j]){
pathcnt[j] += pathcnt[e];
if(res[j]<num[j] + res[e]){
res[j] = num[j] + res[e];
path[j] = e;
}
}
}
}
int mindis = INF1;e = n;
for(int j=0;j<n;j++){
if(!vis[j]&&dis[j]<mindis){
mindis = dis[j];
e = j;
}
}
if(e==n) break;
}
}
int main() {
cin >> n >> m >> s >> d;
for(int i=0;i<n;i++) {
scanf("%d",num+i); res[i] = num[i];
}
int x,y,z,h;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
edge[i][j]=edge[i][j]=INF1;
}
edge[i][i] = 0;
}
for(int i=0;i<m;i++){
scanf("%d%d%d",&x,&y,&z);
edge[x][y]=edge[y][x]= z;
}
dijkstra();
vector<int> p;
h = d;
while(h!=-1){
p.push_back(h);
h = path[h];
}
cout << pathcnt[d] << " " << res[d] << endl;
for(int i=p.size()-1;i>=0;i--){
if(i==p.size()-1) cout << p[i];
else cout << " " << p[i];
}
return 0;
}