简要题意: 给定一个有向图,求从源点开始到各点的最短路。 前置知识: 首先,我们考虑把原来 对于每个节点,松弛相邻节点,这部分无法优化。 但是寻找 怎么实现呢? 考虑一开始源点入队,队列记录每个点的 当前 对当前节点,把所有相邻的节点松弛一遍,并把松弛成功的节点入队。 但是你发现一个问题,如果一个点被它相邻的点同时更新多次,就会入队多次,然后把一模一样的松弛进行很多遍,然后 所以 因为我们开的是优先队列,因此入队的节点距离小的在前,每次对于相同的一个节点,先遍历的一定最优。因此可以开一个哈希记录是否走过,走过则不走即可。 时间复杂度: 实际得分:
Dijkstra 的算法考虑优化。
dis 最小值的过程,我们可以用 优先队列(即小根堆)实现。
dis 最小值 和编号。
O(n2) 没了。
O(nlogn).
O(100pts).#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; const int N=2e5+1; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();} int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q; int n,m,s,dis[N]; bool vis[N]; vector<pair<int,int> > G[N]; inline void Dijkstra(int s) { dis[s]=0; q.push(make_pair(0,s)); while(!q.empty()) { int x=q.top().second; q.pop(); if(vis[x]) continue; vis[x]=1; //判断哈希 // printf("%dn",x); for(int i=0;i<G[x].size();i++) { int v=G[x][i].first,w=G[x][i].second; if(dis[v]>dis[x]+w) { dis[v]=dis[x]+w; if(!vis[v]) q.push(make_pair(dis[v],v)); //松弛入队 } } } } int main(){ n=read(),m=read(),s=read(); memset(dis,0x3f,sizeof(dis)); while(m--) { int u=read(),v=read(),w=read(); G[u].push_back(make_pair(v,w)); } Dijkstra(s); for(int i=1;i<=n;i++) printf("%d ",dis[i]); puts(""); return 0; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算