1111. Online Map (30)

本文介绍了一种基于Dijkstra算法实现的双目标路径优化方案,该方案能够在找到最短路径的同时考虑时间因素,适用于需要同时优化距离和时间的应用场景。通过使用递归方式回溯最短路径和最快路径,并比较两种路径的差异,最终输出最优解。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

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;
}


开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值