市の緊急間のPTA(ダイクストラ)

市の緊急救助チームのヘッドとして、あなたは国の特別なマップを持っています。ロードマップに表示するには、都市と都市との接続のいくつかのより急速な分散を有します。そして、二つの都市の高速道路の長さを結ぶ各都市ごとに救助隊の数は、地図上にマークされています。他の都市はあなたに緊急電話を持っていますが、あなたの使命は、多くの救助隊として召集するための方法に沿って、同時に、できるだけ早く事件に駆けつけレスキューチームをリードすることです。

入力フォーマット:

最初の行の入力は、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;
}
公開された79元の記事 ウォン称賛37 ビュー8878

おすすめ

転載: blog.csdn.net/SinclairWang/article/details/104156922