稠密图
dijkstra
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e4+10;
int dist[N];
int g[501][501];
int n,m;
bool st[501];
int dijk()
{
memset(dist, 0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
}
st[t]=true;
for(int j=1;j<=n;j++)
{
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
if(dist[n]==0x3f3f3f3f) return -1;
return dist[n];
}
int main()
{
cin>>n>>m;
memset(g,0x3f,sizeof g);
while(m--)
{
int x,y,z;
cin>>x>>y>>z;
g[x][y]=min(g[x][y],z);
}
printf("%d",dijk());
return 0;
}
bellman-ford
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5+10;
struct Node
{
int a,b,w;
};
int dist[510];
int main()
{
int n,m;
cin>>n>>m;
vector<Node> q;
for(int i=0;i<m;i++)
{
int x,y,z;
cin>>x>>y>>z;
q.push_back({x,y,z});
}
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++)
for(int j=0;j<q.size();j++)
dist[q[j].b]=min(dist[q[j].b],dist[q[j].a]+q[j].w);
if(dist[n]>0x3f3f3f3f/2) cout<<-1;
else
cout<<dist[n];
return 0;
}
稀疏图
dijkstra邻接表写法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 3e6+10;
typedef pair<int, int> PII;
int h[N],e[N],ne[N],idx,w[N];
int n,m;
int dist[N];
bool st[N];
void insert(int a,int b,int c)
{
e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
}
int djs()
{
memset(dist,0x3f,sizeof dist);
priority_queue<PII,vector<PII>,greater<PII>> q;
dist[1]=0;
q.push({0,1});
while(q.size())
{
auto t=q.top();
q.pop();
int ver=t.second,distance=t.first;
if(st[ver]) continue;
st[ver]=true;
for(int i=h[ver];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>dist[ver]+w[i])
{
dist[j]=dist[ver]+w[i];//注意是起点加权重,参考迪阶斯特拉I
q.push({dist[j],j});
}
}
}
if(dist[n]==0x3f3f3f3f) return -1;//注意精度问题
return dist[n];
}
int main()
{
memset(h, -1, sizeof h);
cin>>n>>m;
while (m -- )
{
int x,y,z;
cin>>x>>y>>z;
insert(x,y,z);
}
cout<<djs()<<endl;
return 0;
}
dijkstra二维vector代替邻接表
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 2e5+10;
typedef pair<int, int> PII;
vector<PII> h[N];
int dist[N];
int n,m;
bool st[N];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<PII,vector<PII>,greater<PII>> q;
q.push({0,1});
while(q.size())
{
auto t=q.top();
q.pop();
int v=t.second;
if(st[v]) continue;
st[v]=true;
for(auto i:h[v])
{
int j=i.first,w=i.second;
if(dist[j]>dist[v]+w)
{
dist[j]=dist[v]+w;
q.push({dist[j],j});
}
}
}
if(dist[n]==0x3f3f3f3f) return -1;
return dist[n];
}
int main()
{
cin>>n>>m;
while (m -- )
{
int a,b,c;
cin>>a>>b>>c;
h[a].push_back({b,c});
}
cout<<dijkstra()<<endl;
return 0;
}
存在负权边
spfa
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5+10;
typedef pair<int, int> PII;
vector<PII> h[N];
int dist[N];
int q[N];
int hh=0,tt=-1;
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
int x,y,z;
cin>>x>>y>>z;
h[x].push_back({y,z});
}
memset(dist,0x3f,sizeof dist);
dist[1]=0;
q[++tt]=1;
while(hh<=tt)
{
int t=q[hh++];
for(auto j:h[t])
if(dist[j.first]>dist[t]+j.second)
{
dist[j.first]=dist[t]+j.second;
q[++tt]=j.first;
}
}
if(dist[n]>0x3f3f3f3f/2) puts("impossible");
else
cout<<dist[n]<<endl;
return 0;
}