最短路径----dijkstra-----初学者笔记

" 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。"

基本思想
起点到终点的路径中,会有中转点;那么如果我们要求出这条路径的最小值,就应该找到到这个中转点的最优路径。
因此,我们可以将所有的点分为两类:红点与黑点。出发点记为红点(红点是到达下一个黑点的中转点);我们以每一个新生成的红点(即被确定了路径的黑点)为起点,枚举这个起点可以通向的所有黑点(不经过其他中转点),比较这些通路的长度,选择最小的那条,将那条边连接的黑点变为红点;重复操作直到所有黑点都变为红点。用dis[i]记录距离并不断更新,下面举个例子
最短路径----dijkstra-----初学者笔记_第1张图片
咱们别管方向,忽略箭头
例如从红点1出发,dis[1]=0,其他dis[i]=0x7ffffff;
此时更新与其相连的黑点2,4,5:dis[2]=10,dis[4]=30,dis[5]=100;
选择最短:将2变为红点;
又从2出发,又选择最小变为红点,即将dis[3]更新为10+50=60
不断循环下去—,意思就到这儿(图不是很好,不过应该懂了
#include
using namespace std;
代码
‘int n,k,t;
int first[100001];得到的以点i为起点的最新一条边的编号
int next[100001];
int size=0;
int v[100001];记录边i的终点编号
int c[100001];//记录边i的权值
int p[100001],f[100001];
bool exist[100001];
priority_queue >q;//定义大根堆 ,乘-1变为小根堆,相当于结构体
不懂看转载:优先队列
void inser(int x,int y,int w)//建立邻接表
{
size++;
next[size]=first[x];
first[x]=size;
v[size]=y;
c[size]=w;
}

void dijstrar()注意,dijkstra是关键字
{
f[t]=0;即上面说到的dis[i];
q.push(make_pair(0,t));总长度为0,起点t
while(!q.empty())如果队列不为空 ==不懂?==看 转载优先队列
{
int u=q.top().second;//取出这个点
q.pop();出队
for(int e=first[u];e;e=next[e])//枚举以这个点为起点的所有边
{
int g=v[e];//e边的终点记为g点
if(f[u]+c[e]中转点u的最短路径+e边的长度
{
f[g]=f[u]+c[e];
q.push(make_pair(-f[g],g));入队;注意负号(这样是小根堆,即元素自动从小到大排列)
}
}
}
}

int main()
{
cin>>n>>k>>t;n个点,k条边,起点t
for(int i=1;i<=k;i++)
{
int x,y,w;
cin>>x>>y>>w;
inser(x,y,w);
inser(y,x,w);
}

memset(exist,false,sizeof(exist));
fill(f+1,f+n+1,1000000000);

dijstrar(); 

cout<

}

希望指出错误并多多指教!欢迎评论~

你可能感兴趣的:(最短路径)