dijkstra
有负环也资磁√
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define inf 233333333333 using namespace std; int cost[1000][1000];//e=(u,v)的权值 int d[1000];//顶点s出发的最短距离 bool used[1000];//已经使用过的图 int n;//顶点数 void dijkstra(int s)//从s出发到各个顶点的最短距离 { memset(d,127/3,sizeof(d)); memset(used,0,sizeof(used)); d[s]=0; while(true) { int v=-1; //从尚未使用过的顶点中选择一个距离最小的顶点 for(int i=0;i<n;++i) { if(!used[i]&&(v==-1||d[i]<d[v]))v=i; } if(v==-1)break; used[v]=true; for(int i=0;i<n;++i) { d[i]=min(d[i],d[v]+cost[v][i]); } } }
↑没加堆优化
选定起点,将其加入队列【队列中为待访问的点】;
while (队列不为空)
1) 把队列中离起点最短的点提出来(用优先队列实现);
2) 查看所有以这个点为起点的边,更新距离目标点的最短距离( dis[目标点] > dis[当前点] + w[当前边] 的话 )。一旦更新,就把目标点丢到队列里去。
然后dis[k]就是起点到目标点的最短距离了。
加堆优化
模板题:
https://www.luogu.org/problem/show?pid=3371
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #define maxn 500005 using namespace std; int n,m,s; int to[maxn],next[maxn],last[maxn],w[maxn]; int ecnt; int dis[10005]; bool vis[10005]; void ins(int a,int b,int c) { to[++ecnt]=b; next[ecnt]=last[a]; last[a]=ecnt; w[ecnt]=c; } struct node { int x,dist; }; bool operator <(node a,node b) { return a.dist>b.dist; } priority_queue <node>q; int main() { cin>>n>>m>>s; int a,b,c; for(int i=1;i<=m;++i) { scanf("%d%d%d",&a,&b,&c); ins(a,b,c); } memset(dis,0x3f,sizeof(dis)); node tmp; tmp.x=s; tmp.dist=0; q.push(tmp); while(!q.empty()) { tmp=q.top(); int now=tmp.x,dist=tmp.dist; q.pop(); if(vis[now])continue; vis[now]=1; dis[now]=dist; for(int i=last[now];i;i=next[i]) { if(!vis[to[i]]) { tmp.x=to[i]; tmp.dist=dis[now]+w[i]; q.push(tmp); } } } for (int k = 1; k <= n; k++) { printf("%d ", dis[k] == 0x3f3f3f3f ? 2147483647 : dis[k]); } return 0; }