DIJ - Heat Wave G - 洛谷 P1339
题目描述
有一个 n 个点 m 条边的无向图,请求出从 s 到 t 的最短路长度。
输入格式
第一行四个正整数 n,m,s,t。 接下来 m 行,每行三个正整数 u,v,w表示一条连接 u,v 长为 w 的边。
输出格式
输出一行一个整数,表示答案。
输入输出样例
输入
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
输出
7
说明/提示
【数据范围】
对于 100% 的数据,1≤n≤2500,1≤m≤6200,1≤w≤1000。
【样例说明】
5→6→1→4 为最短路,长度为 3+1+3=7。
模 板 题 , 由 于 1 ≤ n ≤ 2500 , 1 ≤ m ≤ 6200 , 模板题,由于1≤n≤2500,1≤m≤6200, 模板题,由于1≤n≤2500,1≤m≤6200,
① 、 朴 素 版 d i j k s t r a 算 法 的 时 间 复 杂 度 为 O ( n 2 ) , 可 行 。 ①、朴素版dijkstra算法的时间复杂度为O(n^2),可行。 ①、朴素版dijkstra算法的时间复杂度为O(n2),可行。
② 、 堆 优 化 d i j k s t r a 算 法 的 时 间 复 杂 度 为 O ( m l o g n ) , 可 行 。 ②、堆优化dijkstra算法的时间复杂度为O(mlogn),可行。 ②、堆优化dijkstra算法的时间复杂度为O(mlogn),可行。
③ 、 s p f a 算 法 的 时 间 复 杂 度 为 O ( n m ) , 可 行 。 ③、spfa算法的时间复杂度为O(nm),可行。 ③、spfa算法的时间复杂度为O(nm),可行。
这 里 注 意 无 向 图 边 的 数 量 要 开 两 倍 。 这里注意无向图边的数量要开两倍。 这里注意无向图边的数量要开两倍。
这 里 贴 出 堆 优 化 d i j k s t r a 代 码 : 这里贴出堆优化dijkstra代码: 这里贴出堆优化dijkstra代码:
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define P pair<int,int>
using namespace std;
const int N=2510,M=6200*2+10;
int n,m,S,T,e[M],ne[M],h[N],w[M],idx;
int dis[N];
bool st[N];
void add(int a,int b,int c)
{
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
int dijkstra()
{
memset(dis,0x3f,sizeof dis);
dis[S]=0;
priority_queue<P,vector<P>,greater<P> > heap;
heap.push({0,S});
while(heap.size())
{
P t=heap.top();
heap.pop();
int id=t.second;
if(st[id]) continue;
st[id]=true;
for(int i=h[id];~i;i=ne[i])
{
int j=e[i];
if(dis[j]>dis[id]+w[i])
{
dis[j]=dis[id]+w[i];
heap.push({dis[j],j});
}
}
}
return dis[T];
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m>>S>>T;
int a,b,c;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
cout<<dijkstra()<<endl;
return 0;
}