核心思路
贪心,将图划分为两个部分,一个部分求出来了当前最短路,另一个部分是未处理的。每次添加一个距离前者最近的一个后者中的点,然后再次更新(全图不是单个部分),只到全部点都在前一个部分中了。
样题
参考我前一篇博客吧,今天时间紧来不及写了,抱歉。
代码(堆优化)
优化了找最近点的步骤(N 变为 log N)
#include<bits/stdc++.h>
using namespace std;
const int MMax = 2147483647;
struct edge{
int v,w;//v 表示 去的节点,w 表示 权值。
};
struct node {
int dis, u;
bool operator>(const node& a) const { return dis > a.dis; }
};
vector<edge> g[10010];
int n,m,s;
priority_queue<node, vector<node>, greater<node> > q;
int dis[100010], vis[100010];
void dijk(int s){
for(int i = 1;i <= n;i++){
dis[i] = MMax;
}
dis[s] = 0;
vis[s] = 1;
q.push(node{0,s});
while(!q.empty()){
int u = q.top().u;
q.pop();
vis[u] = 0;
for(int i = 0;i < g[u].size();i++){
int v = g[u][i].v,w = g[u][i].w;
if(dis[v] > dis[u]+w){
dis[v] = dis[u]+w;
if(!vis[v]){
q.push(node{dis[v],v});
vis[v] = 1;
}
}
}
}
}
int main() {
cin>>n>>m>>s;
for(int i = 1;i <= m;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(edge{v,w});
}
dijk(s);
for(int i =1 ;i <= n;i++){
cout<<dis[i]<<" ";
}
}
也是一次过