应用的是dijkstra算法,这种算法的思想类似于贪心。
首先,将所有点分为已知最短路和未知最短路两类。开始时,只有出发点的最短路已知,为0,其余点都标记为正无穷。我们要求出出发点到所有点的最短路径,因此进行点数轮循环,每轮循环中,遍历与已知点间有边相连的点,更新与出发点的最短路径。然后从所有更新的路径值中选出最小值,将对应点加入已知最短路径类,循环操作即可。
还有一点,就是选最小值时,要用堆进行优化,可以将时间复杂度将至O((n+m)log2n)级别,否则是O方复杂度,妥妥超时。
#include<cstdio> #include<queue> #define maxm 200010 #define maxn 100010 #define INF 2147483647 using namespace std; int head[maxn],cnt; int dis[maxn]; int vis[maxn]; struct Edge { int nxt,to,weight; } edge[maxm]; void add(int x,int y,int z) { edge[++cnt].nxt = head[x]; edge[cnt].to = y; edge[cnt].weight = z; head[x] = cnt; } priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > >q; int main() { int n,m,s; scanf("%d%d%d",&n,&m,&s); for(int i = 1; i <= m; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } for(int i = 1; i <= n; i++) dis[i] = INF; dis[s] = 0; q.push(make_pair(0,s)); while(!q.empty()) { int emmm = q.top().second; q.pop(); if(vis[emmm]) continue; vis[emmm] = 1; for(int i = head[emmm]; i; i = edge[i].nxt) { if(dis[emmm] != INF && dis[edge[i].to] > dis[emmm] + edge[i].weight) { dis[edge[i].to] = dis[emmm] + edge[i].weight; q.push(make_pair(dis[edge[i].to],edge[i].to)); } } } for(int i = 1; i <= n; i++) printf("%d ",dis[i]); return 0; }