移動:自分のブログ
トピック
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;
}