基本実験6-2.5都市間の緊急救助(25ポイント)

準備するアレイ:

G [] []グラフは隣接行列として格納さ無限大に初期化され自己から自己へと0に初期化されます。dist[]は頂点からソースまでの距離を格納し、無限大初期化されます。pre[]は、パスを出力するために頂点の先行ノードを格納します。 、-1初期化;

vis []は、頂点がfalseに初期化されたセットSに含まれていることを示すために使用されます。num[]は、0に初期化された最短パスの数を格納するために使用されます。Weight[]は、各ポイントでのレスキューチームの数、つまりポイントの重みを格納します。 、初期化せずに、タイトルで指定されたデータを直接読み込むだけです。

W []は、ソースから頂点までのパスに沿ったレスキューチームの総数を格納するために使用され、0に初期化されます

この質問の基本的な考え方はDijkstraアルゴリズムですが、この質問は重みのポイントを追加し、最短パスの長さを記録します。したがって、dist []が同じ場合、レスキューチームの数が増えるかどうかを確認する必要があります。増加する場合は、レスキューチームの数W []、プリカーサー配列pre []、および最短パスの数num []を更新します。レスキューチームの数が増えない場合は、最短パスの数も更新することを忘れないでください!(ここでミスをすると、テストポイント1が失敗しました)。

Dijkstraアルゴリズムに入った後、ソースポイントの関連データを初期化する必要があります:dist [S] = 0; pre [S] = -1; num [S] = 1(自分自身への道は1つしかないため、Grandma Chenmoocは教えています); W [S] = Weight [S];注:Sは後で最初のループで処理されるため、vis [S]をtrueに初期化しないでください。

初期化が完了したら、通常のDijkstra操作を開始できます。最初に含まれていない最小のdist []を見つけ、次にそれをセットSに含め、次にそれがSに含まれた後に隣接するサークルに影響するかどうかを確認し、影響する場合はそれに応じて更新します。

この質問のコードは次のとおりです。

#include<stdio.h>
#include<stack>
#define INF 10000000
using namespace std;
#define MAXV 505
int n, G[MAXV][MAXV];
int dist[MAXV];
int pre[MAXV];
bool vis[MAXV] = {false};
int num[MAXV];//路径的数目
int Weight[MAXV];//点权
int W[MAXV];//从原点到某个顶点的城市救援队的数目
void Dijkstra(int S)
{
	int i,j,k,z;
	int MinDist,MinV;
	/*对数据进行必要的基础准备*/
	dist[S] = 0;
	pre[S] = -1;
	num[S] = 1;
	W[S] = Weight[S];
	/*下面正式进入Dijkstra*/
	for(i=0; i<n; i++)
	{
		MinDist = INF; MinV = -1;
		for(j=0; j<n; j++)//找到未被访问过的dist[]
		{
			if(vis[j]==false&&dist[j]<MinDist)
			{
				MinDist = dist[j];
				MinV = j;
			}
		}
		if(MinV == -1) return;
		/*没有退出循环说明找到了,继续执行后面的步骤*/
		vis[MinV] = true;
		for(k=0; k<n; k++)
		{
			if(G[MinV][k]<INF&&vis[k]==false)
			{
				if(dist[MinV]+G[MinV][k] < dist[k])
				{
					dist[k] = dist[MinV] + G[MinV][k];
					pre[k] = MinV;
					num[k] = num[MinV];
					W[k] = W[MinV] + Weight[k];
				}
				else if((dist[MinV]+G[MinV][k]==dist[k])&&(W[MinV]+Weight[k]>W[k]))
				{
					pre[k] = MinV;
					num[k] = num[MinV] + num[k];
					W[k] = W[MinV] + Weight[k];
				}
				else if(dist[MinV]+G[MinV][k]==dist[k])
					num[k] = num[MinV] + num[k];
			}
		}
	}
}
int main()
{
	int N,M,S,D;
	int i,j;
	scanf("%d %d %d %d",&N,&M,&S,&D);
	for(i=0; i<N; i++)
	{
		scanf("%d",&Weight[i]);
	}
	int V1,V2,L;
	/*初始化*/
	n = N;
	for(i=0; i<n; i++)
		for(j=0; j<n; j++)
		{
			G[i][j] = INF;
		}
	/*初始化*/	
	for(i=0; i<M; i++)
	{
		scanf("%d %d %d",&V1,&V2,&L);
		G[V1][V2] = L;
		G[V2][V1] = L;
	}
	for(i=0; i<n; i++)
	{
		pre[i] = -1;
		num[i] = 0;
		dist[i] = INF;
		W[i] = 0;
		G[i][i] = 0;
	}
	/*初始化*/
	Dijkstra(S);
	stack<int> q; int path;
	printf("%d %d\n",num[D],W[D]);
	while(D!=-1)
	{
		q.push(D);
		D = pre[D];
	}
	int count = q.size();
	for(i=0; i<count-1; i++)
	{
		path = q.top(); q.pop();
		printf("%d ",path);
	}
	printf("%d",q.top());
	return 0;
}

 

おすすめ

転載: blog.csdn.net/yiwaite/article/details/100181938