Dijkstra+递归
和1018题类似
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int INF = 0x3fffffff;
const int MAX = 510;
int d[MAX],t[MAX];
int G[MAX][MAX],T[MAX][MAX];
bool visited[MAX];
//vector<int> dpre,tpre;
int dpre[MAX],tpre[MAX];
int n , m , s , e;
void DijkstraPath(int s){
fill(d,d+MAX,INF);
fill(t,t+MAX,INF);
for(int i=0;i<n;i++){
dpre[i]=i;
visited[i]=false;
}
d[s]=0;t[s]=0;
for(int i=0;i<n;i++){
int u=-1,min=INF;
for(int j=0;j<n;j++){
if(visited[j]==false&&d[j]<min){
u=j;
min=d[j];
}
}
if(u==-1) return;
visited[u]=true;
for(int v=0;v<n;v++){
if(visited[v]==false&&G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];
t[v]=t[u]+T[u][v];
dpre[v]=u;
}
else if(d[v]==d[u]+G[u][v]&&t[u]+T[u][v]<t[v]){
t[v]=t[u]+T[u][v];
dpre[v]=u;
}
}
}
}
}
//最快且节点最少,节点最少可以在T[MAX][MAX]上设置一个路径上权重都为1的GT[MAX][MAX]
int GT[MAX][MAX];//有路径值为1,没有为INF
int dt[MAX];
void DijkstraTime(int s){
fill(t,t+MAX,INF);
fill(dt,dt+MAX,INF);
for(int i=0;i<n;i++){
tpre[i]=i;
visited[i]=false;
}
dt[s]=0;t[s]=0;
for(int i=0;i<n;i++){
int u=-1,min=INF;
for(int j=0;j<n;j++){
if(visited[j]==false&&t[j]<min){
u=j;
min=t[j];
}
}
if(u==-1) return;
visited[u]=true;
for(int v=0;v<n;v++){
if(visited[v]==false&&T[u][v]!=INF){
if(t[u]+T[u][v]<t[v]){
t[v]=t[u]+T[u][v];
dt[v]=dt[u]+GT[u][v];
tpre[v]=u;
}
else if(t[v]==t[u]+T[u][v]&&dt[u]+GT[u][v]<dt[v]){
dt[v]=dt[u]+GT[u][v];
tpre[v]=u;
}
}
}
}
}
vector<int> dispath,timepath;
void DFSdis(int s,int e){//起点和终点,从终点开始递归
if(e==s){
dispath.push_back(e);
return;
}
DFSdis(s,dpre[e]);
dispath.push_back(e);
}
void DFStime(int s,int e){//起点和终点,从终点开始递归
if(e==s){
timepath.push_back(e);
return;
}
DFStime(s,tpre[e]);
timepath.push_back(e);
}
int dis=0,time1=0;
void Distance(){
for(int i=0;i<dispath.size()-1;i++){
dis+=G[dispath[i]][dispath[i+1]];
}
}
void Time(){
for(int i=0;i<timepath.size()-1;i++){
time1+=T[timepath[i]][timepath[i+1]];
}
}
int main(){
fill(G[0],G[0]+MAX*MAX,INF);
fill(T[0],T[0]+MAX*MAX,INF);
fill(GT[0],GT[0]+MAX*MAX,INF);
int itemp,jtemp,tag,distemp,timetemp;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d%d%d",&itemp,&jtemp,&tag,&distemp,&timetemp);
if(tag==0){
G[itemp][jtemp]=G[jtemp][itemp]=distemp;
T[itemp][jtemp]=T[jtemp][itemp]=timetemp;
GT[itemp][jtemp]=GT[jtemp][itemp]=1;
}
else if(tag==1){
G[itemp][jtemp]=distemp;
T[itemp][jtemp]=timetemp;
GT[itemp][jtemp]=1;
}
}
scanf("%d%d",&s,&e);
DijkstraPath(s);
DijkstraTime(s);
DFSdis(s,e);
DFStime(s,e);
Distance();
Time();
/*for(int i=0;i<n;i++){
printf("%d,",dpre[i]);
}
printf("\n");
for(int i=0;i<n;i++){
printf("%d,",tpre[i]);
}
printf("\n");
for(int i=0;i<dispath.size();i++){
printf("%d->",dispath[i]);
}
printf("\n");
for(int i=0;i<timepath.size();i++){
printf("%d->",timepath[i]);
}
printf("\n");
printf("%d,%d\n",dis,time1);*/
if(dispath==timepath){
printf("Distance = %d; Time = %d: %d",dis,time1,s);
for(int i=1;i<dispath.size();i++){
printf(" -> %d",dispath[i]);
}
printf("\n");
}
else{
printf("Distance = %d: %d",dis,s);
for(int i=1;i<dispath.size();i++){
printf(" -> %d",dispath[i]);
}
printf("\n");
printf("Time = %d: %d",time1,s);
for(int i=1;i<timepath.size();i++){
printf(" -> %d",timepath[i]);
}
printf("\n");
}
return 0;
}
本文介绍了一种基于Dijkstra算法实现的双目标路径优化方案,该方案能够在找到最短路径的同时考虑时间因素,适用于需要同时优化距离和时间的应用场景。通过使用递归方式回溯最短路径和最快路径,并比较两种路径的差异,最终输出最优解。

501

被折叠的 条评论
为什么被折叠?



