最短路基础模板题
P1339 [USACO09OCT] Heat Wave G
题目描述
有一个 n n n 个点 m m m 条边的无向图,请求出从 s s s 到 t t t 的最短路长度。
输入格式
第一行四个正整数
n
,
m
,
s
,
t
n,m,s,t
n,m,s,t。
接下来
m
m
m 行,每行三个正整数
u
,
v
,
w
u,v,w
u,v,w,表示一条连接
u
,
v
u,v
u,v,长为
w
w
w 的边。
输出格式
输出一行一个整数,表示答案。
输入输出样例 #1
输入 #1
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
输出 #1
7
说明/提示
【数据范围】
对于
100
%
100\%
100% 的数据,
1
≤
n
≤
2500
1\le n \le 2500
1≤n≤2500,
1
≤
m
≤
6200
1\le m \le 6200
1≤m≤6200,
1
≤
w
≤
1000
1\le w \le 1000
1≤w≤1000。
【样例说明】
5
→
6
→
1
→
4
5 \to 6 \to 1 \to 4
5→6→1→4 为最短路,长度为
3
+
1
+
3
=
7
3+1+3 = 7
3+1+3=7。
数据量小,可以用各种方法,数据量大,邻接表优先,其次时间需要优化(最短路堆优化)
堆优化的意义:O(n2)->O(mlog(n))
下面直接上代码
一维模拟邻接表(最难理解):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int w[N];
int e[N];
int h[N];
int ne[N];
int dis[N];
int is[N];
int n,m,qq,zz;
int q=0;
void jb(int a,int b,int c){
w[q]=c;
e[q]=b;
ne[q]=h[a];
h[a]=q++;
}
void dij(){
memset(dis,0x3f,sizeof(dis));
dis[qq]=0;
for(int i=0;i<n;i++){
int t=-1;
for(int j=1;j<=n;j++){
if(!is[j]&&(t==-1||dis[j]<dis[t])){
t=j;
}
}
is[t]=1;
for(int j=h[t];j!=-1;j=ne[j]){
int k=w[j];
dis[e[j]]=min(dis[e[j]],dis[t]+k);
}
}
}
int main() {
memset(h,-1,sizeof(h));
cin>>n>>m>>qq>>zz;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
jb(a,b,c);
jb(b,a,c);
}
dij();
cout<<dis[zz];
}`
邻接表+邻接矩阵(压力给到内存):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+10;
int g[N][N];
vector<int>s[N];
int dis[N];
int is[N];
int n,m,q,z;
void dij(){
memset(dis,0x3f,sizeof(dis));
dis[q]=0;
for(int i=0;i<n;i++){
int t=-1;
for(int j=1;j<=n;j++){
if(!is[j]&&(t==-1||dis[j]<dis[t])){
t=j;
}
}
is[t]=1;
for(int k=0;k<s[t].size();k++){
dis[s[t][k]]=min(dis[s[t][k]],dis[t]+g[t][s[t][k]]);
}
}
}
int main() {
//memset(g,0x3f,sizeof(g));
cin>>n>>m>>q>>z;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
g[a][b]=c;
g[b][a]=c;
s[a].push_back(b);
s[b].push_back(a);
}
dij();
cout<<dis[z];
return 0;
}
邻接表(容易理解):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct f{
int w;
int e;
};
vector<f>s[N];
int dis[N];
int is[N];
int n,m,qq,zz;
void dij(){
memset(dis,0x3f,sizeof(dis));
dis[qq]=0;
for(int i=0;i<n;i++){
int t=-1;
for(int j=1;j<=n;j++){
if(!is[j]&&(t==-1||dis[j]<dis[t])){
t=j;
}
}
is[t]=1;
for(int j=0;j<s[t].size();j++){
f z=s[t][j];
dis[z.e]=min(dis[z.e],dis[t]+z.w);
}
}
}
int main() {
//memset(g,0x3f,sizeof(g));
cin>>n>>m>>qq>>zz;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
f z;
z.e=b;
z.w=c;
s[a].push_back(z);
z.e=a;
s[b].push_back(z);
}
dij();
cout<<dis[zz];
}