[テンプレート]単一ソースの最短経路(ダイクストラアルゴリズム)

移動:自分のブログ

トピック

Luogu P4779 [テンプレート]単一ソースの最短パス(標準バージョン)

回答

チェーンフォワードスター(エッジストレージ構造):リンクリストの構造と検索トラバーサル方法は同じで、唯一の違いは挿入位置です。チェーンフォワードスターは、リストの先頭に毎回新しい要素を挿入します。各ノードのリンクリストを作成し、このノードのすべての出力エッジを保存します。

ダイクストラアルゴリズム:このアルゴリズムでは、すべてのエッジの重みが負でないことが必要です。開始点からi番目のノードまでの最短経路長としてd [i]を定義します。

アルゴリズムの流れ:開始点がsであるとします。1. d [s] = 0とすると、他のd [i]は無限大です。2。マークされていないノードから最小のd [x]を持つノードxを見つけ、xをマークします。3。xのすべての出力エッジxを列挙します。 -> y(エッジの重みはw)、d [y]> d [x] + wの場合、d [y]をd [x] + wで更新4.すべてのノードがマークされるまで2と3を繰り返します。

アルゴリズムの原則:貪欲な思考に基づいています。毎回見つかった最小のd [x]を持つノードは、大きいd [y]によって更新できないため、d [x]はsからxへの最短パスである必要があります。

アルゴリズムの最適化:d [x]の最小値を動的に維持して、検索時間を短縮します。STL優先度キュー(大きなルートパイル)を使用し、STLペアを使用してd [x]とxを格納し、d [x]を-d [x]に変換して格納し、大きなルートパイルを小さなルートパイルに変換します。

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x7fffffff;
const int maxn=1e5+5;
const int maxm=2e5+5;
int n,m,s,c;
bool v[maxn];	//v[]表示是否标记 
int head[maxn],d[maxn];	//head[x]表示节点x的链表头 
struct edge{int to,nxt,w;}e[maxm];
inline void add(int from,int to,int w)	//加边 
{
	e[++c].to=to; e[c].w=w; e[c].nxt=head[from]; head[from]=c;
}
priority_queue<pair<int,int> > q;
inline void dijkstra()
{
	for(int i=1;i<=n;i++) d[i]=inf;
	memset(v,0,sizeof(v));	//初始化 
	d[s]=0; q.push(make_pair(0,s));
	while(q.size())
	{
		int x=q.top().second; q.pop();
		if(v[x]) continue; v[x]=1;
		for(int i=head[x];i;i=e[i].nxt)	//遍历x的所有出边 
		{
			int y=e[i].to;
			if(d[y]>d[x]+e[i].w)
			{
				d[y]=d[x]+e[i].w;
				q.push(make_pair(-d[y],y));
			}
		}
	}
}

int main()
{
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=m;i++)
	{
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
	}
	dijkstra();
	for(int i=1;i<=n;i++) printf("%d ",d[i]);
	
	return 0;
}

おすすめ

転載: blog.csdn.net/zjgmartin/article/details/108415521