刚学迪杰斯特拉,打个模板,方便考古(雾
#include<bits/stdc++.h>
using namespace std;
int cnt = 0; //给每段编号
int head[100086];// 存储头
int dis[100086];// 保存到i最短路
bool vis[100086];//标记是否访问
struct TT{
//存边结构体
int to;// 到哪个节点
int next;//下一个块
int val;// 权值
}edge[100086];
struct T{
//优先队列结构体
int id;// 节点
int c;// 权值
// 重载<符号 构建大/小根堆
bool operator < (const T &x)const {
return c > x.c;//注意:重载后顺序是相反的
}
};
// 迪杰斯特拉正文
void dij(int s){
priority_queue<T> q;// 堆优化
q.push({s,0});//推入起始点
dis[s]=0;// 起始点为0;
while(!q.empty()){
int now = q.top().id;//取出堆顶元素
q.pop();//用完就丢(
if(vis[now]==1){
continue;//如果访问过了,就直接跳过
}
vis[now]=1;//如果没访问过,那就标记一下
for(int u = head[now];u!=-1;u=edge[u].next){//循环递归,直到不能走为止
int v = edge[u].to;
if(vis[v] == 0 && dis[v]>dis[now]+edge[u].val){//如果当前步能够使得路更短,那就更新dis
dis[v]= dis[now]+edge[u].val;
q.push({v,dis[v]});//有新的可能,插入队列
}
}
}
return ;//不写return的都是异类
}
void add(int u,int v,int c){// 加边函数
cnt++;
edge[cnt].to = v;
edge[cnt].val = c;
edge[cnt].next = head[u];//更新新老头
head[u] = cnt;
return ;
}
int main(){
int n,m,s,t;
cnt =0;
memset(head,-1,sizeof head);//别忘记初始化哦
memset(dis,0x3f3f3f3f,sizeof dis);
memset(vis,0,sizeof vis);
cin>>n>>m>>s>>t;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);// 添加单向边
add(b,a,c);// 添加双向边
}
dij(s);//跑一遍
cout<<dis[t]<<endl;//输出s -》 t 的最短路
return 0;
}