最短路模板(Floyd+bellman+spfa+Dijkstra)
最短路问题
1、单源最短路
a、所有权边都是正数:
Dijkstra算法 :朴素算法(O(mn)) 堆优化(O(mlogn))
b、有负数权变:
Bellman算法 : O(mn)
Spfa算法:(一般情况O(m),最坏情况 O(mn)) (慎用)
2、多源最短路
Floyd算法: O(n^3)
Dijkstra
#include<bits/stdc++.h>
#define ll long long
#define MOD 998244353
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int NUM = 1005;
struct edge{
int from,to,w;
edge(int a,int b,int c){from=a;to=b;w=c;}
};
vector<edge>e[NUM];
struct s_node{
int id,n_dis;
s_node(int b,int c){id=b;n_dis=c;}
bool operator < (const s_node &a) const
{return n_dis>a.n_dis;}
};
int n,m;
int pre[NUM];
void print_path(int s,int t)
{
if(s==t)printf("%d",s);
print_path(s,pre[t]);
printf("%d",t);
}
void Dijkstra(int s) //s是起点
{
int dis[NUM];
bool done[NUM];
for(int i=1;i<=n;i++){dis[i]=INF;done[i]=false;}
dis[s]=0;
;priority_queue<s_node>Q
Q.push(s_node(s,dis[s]));
while(!Q.empty())
{
s_node u=Q.top();
Q.pop();
if(done[u.id])continue;
done[u.id]=true;
for(int i=0;i<e[u.id].size();i++){
edge y=e[u.id][i];
if(done[y.to])continue;
if(dis[y.to]>y.w+u.n_dis){
dis[y.to]=y.w+u.n_dis;
Q.push(s_node(y.to,dis[y.to]));
pre[y.to]=u.id;
}
}
}
printf("%d\n",dis[n]);
}
int main()
{
while(~scanf("%d %d",&n,&m)){
if(n==0&&m==0)break;
for(int i=1;i<=n;i++){
e[i].clear();
}
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
Dijkstra(1);
}
return 0;
}
//朴素
//-----------------------
const int NUM = 1005;
int mp[NUM][NUM];
int dis[NUM];
bool vis[NUM];
int n,m;
void Dijkstra()
{
int pos=1,minn;
for(int i=1;i<=n;i++)vis[i]=false;
dis[1]=0;
vis[1]=1;
for(int i=1;i<=n;i++){
minn=INF;
for(int j=1;j<=n;j++){
if(vis[j]==0&&minn>dis[j]){
minn=dis[j];
pos=j;
}
}
vis[pos]=1;
for(int j=1;j<=n;j++){
if(vis[j]==0&&dis[j]>dis[pos]+mp[pos][j]){
dis[j]=dis[pos]+mp[pos][j];
}
}
}
printf("%d\n",dis[n]);
}
Bellman
#include<bits/stdc++.h>
#define ll long long
#define MOD 998244353
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int NUM = 105;
struct edge{int u,v,w;}e[10005];
int n,m,cnt;
int pre[NUM];
void print_path(int s,int t)
{
if(s==t){printf("%d",s); return 0;}
print_path(s,pre[t]);
printf("%d",t);
}
void bellman(int s)
{
int d[NUM];
for(int i=1;i<=n;i++)d[i]=INF;
d[s]=0;
for(int k=1;k<=n;k++){
for(int i=0;i<cnt;i++){
int x=e[i].u, y=e[i].v;
if(d[x]>d[y]+e[i].w){
d[x]=d[y]+e[i].w;
pre[x]=y;
}
}
}
printf("%d\n",d[n]);
}
//----------------------------
void bellman(int s) //负圈
{
int d[NUM];
for(int i=1;i<=n;i++)d[i]=INF;
d[s]=0;
int k=0;
bool update=true;
while(update){
k++;
if(k>n){printf("有负圈");}
for(int i=0;i<cnt;i++){
int x=e[i].u,y=e[i].v;
if(d[x]>d[y]+e[i].w){
update=true;
d[x]=d[y]+e[i].w;
//pre[x]=y;
}
}
}
printf("%d\n",d[n]);
}
int main()
{
while(~scanf("%d %d",&n,&m)){
if(n==0||m==0)break;
cnt=0;
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
e[cnt].u=a; e[cnt].v=b; e[cnt].w=c; cnt++;
e[cnt].u=b; e[cnt].v=a; e[cnt].w=c; cnt++;
}
bellman(1); //从1到n的最短路
}
return 0;
}
spfa
#include<bits/stdc++.h>
#define ll long long
#define MOD 998244353
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int NUM=105;
struct edge{
int to,next,w;
edge(int a,int b,int c){to=a;next=b;w=c;}
};
vector<edge>e[NUM];
int n,m;
int pre[NUM];
void print_path(int s,int t)
{
if(s==t)printf("%d",s);
print_path(s,pre[t]);
printf("%d",t);
}
void spfa(int s)
{
int dis[NUM];
bool inq[NUM];
int neg[NUM];
for(int i=1;i<=n;i++){dis[i]=INF;inq[i]=false;neg[i]=0;}
dis[s]=0;
neg[s]=1;
queue<int>Q;
Q.push(s);
inq[s]=true;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
inq[u]=false;
for(int i=0;i<e[u].size();i++){
int v=e[u][i].next,w=e[u][i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
pre[v]=u;
if(!inq[v]){
Q.push(v);
inq[v]=true;
neg[v]++;
if(neg[v]>n){printf("有负圈\n");return;}
}
}
}
}
printf("%d\n",dis[n]);
return;
}
int main()
{
while(~scanf("%d %d",&n,&m)){
if(n==0&&m==0)break;
for(int i=1;i<=n;i++){
e[i].clear();
}
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
spfa(1);
}
return 0;
}
Floyd
#include<bits/stdc++.h>
#define ll long long
#define MOD 998244353
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int NUM = 105;
int graph[NUM][NUM];
int n,m;
void Floyd(int s)
{
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
if(graph[i][k]!=INF){
for(int j=1;j<=n;j++){
if(graph[i][k]+graph[k][j]<graph[i][j])graph[i][j]=graph[i][k]+graph[k][j];
}
}
}
}
printf("%d\n",graph[s][n]);
}
int main()
{
while(~scanf("%d %d",&n,&m)){
if(n==0&&m==0)break;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
graph[i][j]=INF;
}
}
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
graph[a][b]=c;
graph[b][a]=c;
}
Floyd(1);
}
return 0;
}
越自律,越自由