对dijkstra堆优化,
STL的写法比较难懂。
其实更好的可以用spfa。
可以看看这个文章http://blog.csdn.net/qq_35776579/article/details/52453290
也是我的。
~呵呵,推销一下
其实在思想是与普通的一样。
只是~~
运用优先队列时的那个重载运算符比较难懂,应为是大根堆,上面编号大,但是权值小。慢慢理解。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define begin Begin//可能有关键字
#define next Next//可能有关键字
#define mk(a) memset(a,0,sizeof(a))
using namespace std;
const int N=100010,M=10000000,INF=100000000;
int n,m;
struct key{int p,w;};//点的编号,权值
bool operator < (key a , key b)
{
return (a.w>b.w);
}//重载运算符
struct dijkstra
{
int begin[N],next[M],to[M],w[M];//链式前向星的数组
int dist[N],vis[N];//距离数组,判断是否已经修改的数组
int e;
void init()//初始化
{
mk(begin);
mk(vis);
e=0;
}
void add(int x,int y,int z)//链式前向星
{
to[++e]=y;
next[e]=begin[x];
begin[x]=e;
w[e]=z;
}
void getans(int p)
{
priority_queue<key>Q;//STL优先队列
/*
这里优先队列的STL写法是大根堆,所以上面的编号大,但权值小
*/
for(int i=1;i<=n;i++)dist[i]=INF;
dist[p]=0;
Q.push((key){p,0});//处理第一个点
while(!Q.empty())
{
key tmp=Q.top();Q.pop();
int u=tmp.p;
if(vis[u])continue;
vis[u]=1;
for(int i=begin[u];i;i=next[i])
{
int v=to[i];
if(dist[v]>dist[u]+w[i])
{
dist[v]=dist[u]+w[i];
Q.push((key){v,dist[v]});//加入队列
}
}
}
}
void out()
{
for(int i=1;i<=n;i++)
printf("%d ",dist[i]);
printf("\n");
}
};
dijkstra d;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
d.add(x,y,z);
d.add(y,x,z);
}
d.getans(1);//从第一个点开始遍历
d.out();
return 0;
}