一:Dijkstra(适用于无向图,但不适于有负边权的图)
1.朴素dijkstra
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000;
bool sign[N];
int g[N][N];
int dis[N];
int n,m;
int djs()
{
for(int i=0;i<=n;i++)dis[i]=LLONG_MAX/2;
dis[1]=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
if(!sign[j]&&(t==-1||dis[t]>dis[j]))t=j;
sign[t]=1;
for(int j=1;j<=n;j++)
{
dis[j]=min(dis[j],dis[t]+g[t][j]);
}
}
if(dis[n]==LLONG_MAX/2)return -1;
return dis[n];
}
signed main()
{
memset(g,0x3f,sizeof g);
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
g[a][b]=min(g[a][b],c);
}
cout<<djs();
return 0;
}
2.堆优化版dijstra
查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
bool sign[N];
int h[N],e[N],ne[N],w[N],idx,n,m;
int dis[N];
typedef pair<int,int> PII;
int a[1000000];
void add(int x,int y,int z)
{
e[idx]=y;
w[idx]=z;
ne[idx]=h[x];
h[x]=idx++;
}
int djs()
{
for(int i=0;i<=n;i++)dis[i]=LLONG_MAX/2;
dis[1]=0;
priority_queue<PII,vector<PII>,greater<PII>> p;
p.push({0,1});
while(p.size())
{
PII t=p.top();
p.pop();
int dian=t.second,distance=t.first;
if(sign[dian])continue;
sign[dian]=true;
for(int i=h[dian];i!=-1;i=ne[i])
{
int j=e[i];
if(dis[j]>distance+w[i])
{
dis[j]=distance+w[i];
p.push({dis[j],j});
}
}
}
if(dis[n]==LLONG_MAX/2)return -1;
return dis[n];
}
signed main()
{
memset(h,-1,sizeof h);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int j=1;j<=m;j++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
cout<<djs();
return 0;
}
二:Bellman-Ford(图中不能包含权值总和为负的回路)
1.Bellman-Ford算法
查看代码
struct Edge {
int u, v, w;
};
vector<Edge> edge;
int dis[MAXN], u, v, w;
const int INF = 0x3f3f3f3f;
bool bellmanford(int n, int s) {
memset(dis, 0x3f, sizeof(dis));
dis[s] = 0;
bool flag = false;
for (int i = 1; i <= n; i++) {
flag = false;
for (int j = 0; j < edge.size(); j++) {
u = edge[j].u, v = edge[j].v, w = edge[j].w;
if (dis[u] == INF) continue;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
flag = true;
}
}
if (!flag) {
break;
}
}
return flag;
}
2.SPFA队列优化(仅适用有父权边的图)
查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
bool sign[N];
int h[N],e[N],ne[N],w[N],vis[N],idx,n,m,s,t;
int dis[N];
void add(int x,int y,int z)
{
e[idx]=y;
w[idx]=z;
ne[idx]=h[x];
h[x]=idx++;
}
queue<int>q;
int spfa(int s,int t)
{
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=h[x];i!=-1;i=ne[i])
{
int y=e[i];
if(dis[y]>dis[x]+w[i])
{
dis[y]=dis[x]+w[i];
if(!vis[y])
{
q.push(y);
vis[y]=1;
}
}
}
}
if(dis[t]>=0x3f3f3f3f)return -1;
else return dis[t];
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m>>s>>t;
for(int j=1;j<=m;j++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);
}
cout<<spfa(s,t);
return 0;
}
三:Floyd
查看代码
for (k = 1; k <= n; k++) {
for (x = 1; x <= n; x++) {
for (y = 1; y <= n; y++) {
f[x][y] = min(f[x][y], f[x][k] + f[k][y]);
}
}
}