《算法笔记》P385
emmm迪杰斯特拉算法来求图的最短路径,书上的模板套一套就可以了嘛?
方法一:纯Dijkstra代码:
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 510;
const int INF = 1000000000;
//n为顶点数,m为边数,st和ed分别为起点和终点
//G为距离矩阵,c[]记录最小花费,d[]记录最短距离
int n,m,st,ed,G[maxn][maxn],cost[maxn][maxn];
int d[maxn],c[maxn],pre[maxn];
bool vis[maxn] = {false};
void Dijkstra(int s){
fill(d,d+maxn,INF);
fill(c,c+maxn,INF);
for(int i = 0;i <n;i++){
pre[i] = i; //每个前驱设为自身
}
d[s] = 0;
c[s] = 0;
for(int i = 0;i <n;i++){
int u = -1,MIN = INF;
for(int j = 0;j <n;j++){
if(vis[j] == false && d[j] <MIN){
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0;v <n;v++){
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] <d[v]){
d[v] = d[u] + G[u][v];
c[v] = c[u] + cost[u][v];
pre[v] = u;
}
else if(d[u] + G[u][v] == d[v]){
if(c[u] + cost[u][v] <c[v]){
c[v] = c[u] + cost[u][v];
pre[v] = u;
}
}
}
}
}
}
void DFS(int v){
if(v == st){
printf("%d ",v);
return;
}
DFS(pre[v]);
printf("%d ",v);
}
int main(){
scanf("%d%d%d%d",&n,&m,&st,&ed);
int u,v;
fill(G[0],G[0] + maxn*maxn,INF);
for(int i = 0;i <m;i++){
scanf("%d%d",&u,&v);
scanf("%d%d",&G[u][v],&cost[u][v]);
G[v][u] = G[u][v];
cost[v][u] = cost[u][v];
}
Dijkstra(st);
DFS(ed);
printf("%d %d\n",d[ed],c[ed]); //最短距离、最短路径下的最小花费
return 0;
}
/*
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
*/
方法二:Dijkstra + DFS(需处理)
其实感觉这两种方法,纯用迪杰斯特拉似乎比较好操作?
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 510;
const int INF = 1000000000;
int n,m,st,ed,G[maxn][maxn],cost[maxn][maxn];
int d[maxn],mincost = INF; //mincost记录最短路径上的最小花费
bool vis[maxn] = {false};
vector<int> pre[maxn];
vector<int> tempth,path;
void Dijkstra(int s){
fill(d,d+maxn,INF);
d[s] = 0;
for(int i = 0;i <n;i++){
int u = -1,MIN = INF;
for(int j = 0;j <n;j++){
if(vis[j] == false && d[j] <MIN){
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0;v <n;v++){
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] <d[v]){
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u] + G[u][v] == d[v]){
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v){
if(v == st){
tempth.push_back(v);
int tempcost = 0;
for(int i = tempth.size() - 1;i > 0;i--){
int id = tempth[i],idnext = tempth[i-1];
tempcost += cost[id][idnext];
}
if(tempcost <mincost){
mincost = tempcost;
path = tempth;
}
tempth.pop_back();
return;
}
tempth.push_back(v);
for(int i = 0;i <pre[v].size();i++){
DFS(pre[v][i]);
}
tempth.pop_back();
}
int main(){
scanf("%d%d%d%d",&n,&m,&st,&ed);
int u,v;
fill(G[0],G[0] + maxn*maxn,INF);
fill(cost[0],cost[0] + maxn*maxn,INF);
for(int i = 0;i <m;i++){
scanf("%d%d",&u,&v);
scanf("%d%d",&G[u][v],&cost[u][v]);
G[v][u] = G[u][v];
cost[v][u] = cost[u][v];
}
Dijkstra(st);
DFS(ed);
for(int i = path.size() - 1;i >= 0;i--){
printf("%d ",path[i]);
}
printf("%d %d\n",d[ed],mincost);
return 0;
}