最短路模板题
坑点:题目可能会给你重边,只要选最小的一条即可
1、dij算法
#include <bits/stdc++.h>
using namespace std;
int n,m,s,t;
int dis[1010];
bool vis[1010];
int G[1010][1010];
int dij(int s,int t){
for(int i = 1;i <= n;i++) //初始化距离表
dis[i] = G[s][i];
for(int i = 1;i < n;i++){
int Min = 0x3f3f3f3f;
int index = 0;
for(int j = 1;j <= n;j++){ //找到当前未被标记的最小边
if(!vis[j] && dis[j] < Min){
Min = dis[j];
index = j;
}
}
vis[index] = 1; //标记当前边,并确定为最短边
for(int j = 1;j <= n;j++){
dis[j] = min(dis[j],G[j][index]+dis[index]);
}
}
return dis[t];
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
memset(dis,0x3f,sizeof(dis));
memset(G,0x3f,sizeof(G));
cin>>n>>m>>s>>t;
while(m--){ //读入图
int a,b,v;
cin>>a>>b>>v;
G[a][b] = min(v,G[a][b]); //可能会出现重边,选最小的那条
G[b][a] = min(v,G[b][a]);
}
for(int i = 1;i <= n;i++) //置对角线为0
G[i][i] = 0;
int tmp = dij(s,t);
if(tmp >= 0x3f3f3f3f) cout<<-1; //若距离为无穷大,则输出-1
else cout<<tmp;
return 0;
}
2、bellman ford算法(适用于带负边但不含负环的图)
#include <bits/stdc++.h>
using namespace std;
int n,m,s,t;
int dis[1010];
bool vis[1010];
int G[1010][1010];
int BF(int s,int t){
for(int i = 1;i <= n;i++) //初始化距离表
dis[i] = G[s][i];
bool flag = true;
while(flag){
flag = false;
for(int i = 1;i <= n;i++){ //对所有能松弛的点都松弛
for(int j = 1;j <= n;j++){
if(dis[i] > dis[j] + G[i][j]){
dis[i] = dis[j] + G[i][j];
flag = true;
}
}
}
}
return dis[t];
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
memset(dis,0x3f,sizeof(dis));
memset(G,0x3f,sizeof(G));
cin>>n>>m>>s>>t;
while(m--){ //读入图
int a,b,v;
cin>>a>>b>>v;
G[a][b] = min(v,G[a][b]); //可能会出现重边,选最小的那条
G[b][a] = min(v,G[b][a]);
}
for(int i = 1;i <= n;i++) //置对角线为0
G[i][i] = 0;
int tmp = BF(s,t);
if(tmp >= 0x3f3f3f3f) cout<<-1; //若距离为无穷大,则输出-1
else cout<<tmp;
return 0;
}