1、最短路模板
Dijkstra算法:单源最短路,可以使用邻接表建图+优先队列优化
spfa算法:sfl优化+判负环+前向星建图
floyd算法:也可用来判负环,不过时间复杂度贼高,基本没用过
附上一道模板题:hdu1548
Dijkstra实现代码:46ms
#include<bits/stdc++.h>
using namespace std;
const int MAX = 100 + 10;
const int inf = 1e9 + 7;
int N,A,B;
struct Node{
int u;//点
int w;//权值
bool operator <(const Node &a) const{
return a.w<w;
}
};
vector<Node>vec[500];
bool vis[500];
int dis[500];//从起点到i的总长度
void init()
{
for(int i=0;i<=200;i++){
vec[i].clear();
}
memset(vis,0,sizeof(vis));
fill(dis,dis+200+1,inf);
}
void Dijistra(){
dis[A]=0;
priority_queue<Node>Q;
Q.push({A,0});
while(!Q.empty())
{
Node now=Q.top();
Q.pop();
int u=now.u;
if(vis[u])
continue;
vis[u]=1;
int len=vec[u].size();
for(int i=0;i<len;i++){
Node nex=vec[u][i];
int v=nex.u;
int w=nex.w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
Q.push({v,dis[v]});
}
}
}
if(dis[B]==inf)
cout<<-1<<endl;
else
cout<<dis[B]<<endl;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>N){
if(N==0)break;
cin>>A>>B;
init();
int x,y;
for(int i=1;i<=N;i++){//建图
cin>>x;
if(i+x<=N&&i+x>=1){
y=i+x;
vec[i].push_back({y,1});//将x和y连起来,两点间距为1
}
if(i-x<=N&&i-x>=1){
y=i-x;
vec[i].push_back({y,1});
}
}
Dijistra();
}
return 0;
}
Floyd实现代码:873ms
#include<bits/stdc++.h>
using namespace std;
const int maxn = 205;
const int Max = 1e7 + 10;
int N, A, B;
int k[maxn];
int a[maxn][maxn];
int main()
{
ios::sync_with_stdio(false);
while (cin >> N >> A >> B&&N!=0) {
for (int i = 1; i<= N; ++i) {
for (int j = 1; j <= N; ++j) {
if (i == j)
a[i][j] = 0;
else
a[i][j] = Max;
}
}
for (int i = 1; i <= N; ++i) {
cin >> k[i];
if (i + k[i] >= 1 && i + k[i] <= N)
a[i][i + k[i]] = 1;
if(i- k[i] >= 1 && i - k[i] <= N)
a[i][i - k[i]] = 1;
}
for (int k = 1; k <= N; ++k)
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j) {
if (a[i][j] > a[i][k] + a[k][j])
a[i][j] = a[i][k] + a[k][j];
}
if (a[A][B] == Max)
cout << -1 << endl;
else
cout << a[A][B] << endl;
}
return 0;
}
spfa实现代码:(暂时还没写出来,过后补)
2、最短路径记录
未完待续。。。