PAT 甲级 1111 Online Map (30 分)

思路:

1.两次dijskra即可,用dfs会超时,我剪枝剪了好久还是会超时…
2.每次判断是否最短(最快)的时候依据题目中的两个标准;
3.用vector保存每个点可达的下一个点,用邻接矩阵存储距离和时间,用数组标记每个点是否已知最短(最快),用数组记录每个点此刻离起点的距离、最短路径的最短可达时间、最短时间、最短时间的最少周转次数,再用数组保存每个点的最短路径前驱结点和最短时间前驱结点;
4.用递归根据前驱结点数组来写vector;
5.最后判断两个vector是否相等,根据题意输出即可;

代码:

#include<iostream>
#include<vector>
#include<climits>
#include<map>
#include<vector>
using namespace std;
int n,m,pos,des;
int vlen[500][500],vt[500][500];
vector<int> isknown(500),len(500),tlen(500),t(500),cnt(500),lenpre(500),tpre(500);
map<int,vector<int>> mp;
vector<int> lenpath,tpath;
void dijDistance(int node){
	isknown[node]=true;
	for(auto e:mp[node]){
		if(!isknown[e]){
			int a=len[node]+vlen[node][e],b=tlen[node]+vt[node][e];
			if(a<len[e]||(a==len[e]&&b<tlen[e])){
				if(a<len[e]) len[e]=a;
				tlen[e]=b;
				lenpre[e]=node;
			}
		}
	}
	int temp;
	for(temp=0;isknown[temp];temp++);
	for(int i=temp;i<n;i++){
		if(!isknown[i]&&(len[i]<len[temp]||(len[i]==len[temp]&&tlen[i]<tlen[temp])))
			temp=i;
	}
	if(temp==des) return;
	dijDistance(temp);
}
void dijTime(int node){
	isknown[node]=true;
	for(auto e:mp[node]){
		if(!isknown[e]){
			int a=t[node]+vt[node][e],b=cnt[node]+1;
			if(a<t[e]||(a==t[e]&&b<cnt[e])){
				if(a<t[e]) t[e]=a;
				cnt[e]=b;
				tpre[e]=node;
			}
		}
	}
	int temp;
	for(temp=0;isknown[temp];temp++);
	for(int i=temp;i<n;i++){
		if(!isknown[i]&&(t[i]<t[temp]||(t[i]==t[temp]&&cnt[i]<cnt[temp])))
			temp=i;
	}
	if(temp==des) return;
	dijTime(temp);
}
void lenPathPrint(int node){
	if(node!=pos) lenPathPrint(lenpre[node]);
	lenpath.push_back(node);
}
void tPathPrint(int node){
	if(node!=pos) tPathPrint(tpre[node]);
	tpath.push_back(node);
}
int main(){	
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		int v1,v2,oneway;
		scanf("%d%d%d",&v1,&v2,&oneway);
		scanf("%d%d",&vlen[v1][v2],&vt[v1][v2]);
		mp[v1].push_back(v2);
		if(!oneway){
			vlen[v2][v1]=vlen[v1][v2];
			vt[v2][v1]=vt[v1][v2];
			mp[v2].push_back(v1);
		}
	}
	scanf("%d%d",&pos,&des);
	fill(isknown.begin(),isknown.end(),false);
	fill(cnt.begin(),cnt.end(),INT_MAX);
	len=tlen=t=cnt;
	len[pos]=tlen[pos]=t[pos]=cnt[pos]=0;
	dijDistance(pos);
	fill(isknown.begin(),isknown.end(),false);
	dijTime(pos);
	lenPathPrint(des);
	tPathPrint(des);
	if(lenpath==tpath) printf("Distance = %d; Time = %d: %d",len[des],t[des],pos);
	else{
		printf("Distance = %d: %d",len[des],pos);
		for(int i=1;i<lenpath.size();i++) printf(" -> %d",lenpath[i]);
		printf("
Time = %d: %d",t[des],pos);
	}
	for(int i=1;i<tpath.size();i++) printf(" -> %d",tpath[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/yuhan-blog/p/12309004.html