最短経路(ダイクストラアルゴリズム)を解きます

問題の1の説明(PAT A 1003Emergencyからの質問)

市の緊急救助チームのリーダーとして、あなたはあなたの国の特別なマップを与えられています。マップは、いくつかの道路で接続された複数の散乱都市を示しています。各都市と都市の任意のペア間の各道路の長さは救助隊の量は、地図上にマークされています。いくつかの他の都市からあなたへの緊急呼び出しがあった場合、あなたの仕事は、可能な限り迅速な場所にあなたの男性をリードしており、平均時間で、可能な限りの方法でできるだけ多くの手を呼び出します。

入力仕様:
各入力ファイルは、1つのテストケースが含まれています。各テストケースのために、最初の行は、4つの正の整数含ま: -都市の数(及び都市が0からN-1まで番号付けされる)、M - N(≤500)道路の数、C 1およびC 2 -あなたは、現在では、あなたは、それぞれ、保存しなければならないことにある都市。次の行は、i番目の整数はi番目の都市における救助隊の数であるN個の整数を、含まれています。次いで、M行の各々は、それぞれの道路とその道路の長さによって接続都市の対である3つの整数のC 1、C 2、L、道路を説明し、従います。C 1からC 2の少なくとも一つの経路が存在することが保証されます。

出力仕様:
C 1とC 2の間の異なる最短経路の数、あなたはおそらく収集できる救助隊の最大量:各テストケースについては、一列に2つの数値を印刷します。行のすべての数字は正確に一つのスペースで区切らなければならず、行の末尾に許さ余分なスペースがありません。

サンプル入力:

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

サンプル出力:

2 4

タイトルは、おそらく意味します:

Nの都市、Mの記事無向エッジを与えます。複数ある場合は、すべての都市は、すべての既知の右側には、今の最短経路バーの数を求めて最初から最後まで、始まりと終わりを与え、そして最短経路上の救助隊の数ながら、救助隊の数を持っており、次いで、最短経路の数最大合計出力

サンプルは説明:以下に示す、ブラケット各点は右のポイントで、右端が各側でマークされているように、V2にV0からの最短経路は2であり、両者の合計:V0-> V2とV0->をV1-> V2と、2つのパス2,4の右側の点はそれほど大きく選択されます

分析の考え方2:

①私たちは中核主題や最短経路を知ることができるので、我々は最短経路を解決するために、ダイクストラのアルゴリズムを使用することができますが、純粋な異なるダイクストラのアルゴリズムを使用する前に、最短経路の頂点の残りの部分に元から解決するための予備知識で話題の分析が、ここで少しの変更、それが可能であり、より最短経路であり、追加の条件を増加させることができるアルゴリズムDijskstraの変異体である右点に最短経路、最短経路の最大部分の頂点の数を、解決する必要があることです

②最短パスの最大点右を解決し、[]、Wアレイを意味する点の最大重量があるため、最短経路を解決する必要があるため、最初に0、V、ソースSから入手することができ表すwは、我々は、配列を宣言することができ片の数は、我々は、和NUM [S] = 1つの余りNUMの初期化[V] 0にソース点Sから最短パス番号頂点uをNUM配列表現である意味、さらに配列NUMを宣言する必要があります、あなたは、Dの更新に二つの配列を更新する必要があります[v]のとき

③残りのプロセスのソース頂点への最短経路を解く前に、ループ内の電流は、このようなことができるかどうかを確認するために、2つのアレイは、我々が解決する必要が記録相関値を増加させ、その後、判定を追加することを除いて、非常に類似して、中間ノードU V Sは、更新の最小数に、等しくはNUM [V]のパスを等しく到達している頂点からの距離であり、か否か右点増加を決定し、そうであればWよりアップデート[V]右点の

④私たちは解決するために支援するために、上記の問題は、コア又はダイクストラ法に加えて、いくつかの配列を解決しました

3.特定のコードは次のように

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm> 
using namespace std;
const int maxSize = 510;
const int INF = 1000000000;
int n, m, st, ed, G[maxSize][maxSize], weight[maxSize];
int d[maxSize], w[maxSize], num[maxSize];
bool vis[maxSize] = {false};
int pre[maxSize];
void Dijstra(int s){
	fill(d, d + maxSize, INF);
	memset(num, 0, sizeof(num));
	memset(w, 0, sizeof(w));
	d[s] = 0;
	w[s] = weight[s];
	num[s] = 1;
	for(int i = 0; i < n; i++){
		int u = -1, min = INF;
		for(int j = 0; j < n; j++){
			if(vis[j] == false && d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++){
			if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
				d[v] = d[u] + G[u][v];
				w[v] = w[u] + weight[v];
				num[v] = num[u];	
			}else if(d[u] + G[u][v] == d[v]){
				if(w[u] + weight[v] > w[v]){
					w[v] = w[u] + weight[v];
				}
				num[v] += num[u];
			}
		}
	}	
}

int main(void){
	cin >> n >> m >> st >> ed;
	for(int i = 0; i < n; ++i){
		cin >> weight[i];
	}
	int u, v, t;
	fill(G[0], G[0] + maxSize * maxSize, INF);
	for(int i = 0; i < m; i++){
		cin >> u >> v >> t;
		G[u][v] = G[v][u] = t; 
	}
	Dijstra(st);
	cout << num[ed] << " " << w[ed];
}

 

 

おすすめ

転載: blog.csdn.net/qq_39445165/article/details/93225217