1111 Online Map (30 分)
题目地址
优先队列(重载运算符)优化的dijkstra,route很精妙
#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#define INF 0x3fffffff
#define MAX 502
using namespace std;
int n,m;
vector<int> edge[MAX];
int distmap[MAX][MAX];
int timemap[MAX][MAX];
//res:
int mindist,mintime;
vector<int> resDistRoute,resTimeRoute;
struct Vertex{
int x,dist;
bool operator <(const Vertex &v) const{
return dist>v.dist;
}
};
void buildEdge(int st,int ed,int length,int time){
edge[st].push_back(ed);
distmap[st][ed]=length;
timemap[st][ed]=time;
}
void dijkstra1(int st,int ed){
vector<bool> vis(n,false);
vector<int> dist(n,INF),time(n,INF);
vector<vector<int> > route(n);
priority_queue<Vertex> pq;
dist[st]=time[st]=0;
pq.push(Vertex{st,0});
while(!pq.empty()){
int f=pq.top().x;
pq.pop();
if(vis[f]) continue;
vis[f]=true;
route[f].push_back(f);
if(f==ed) break;
for(int i=0;i<edge[f].size();i++){
int to=edge[f][i];
if(vis[to]) continue;
if(dist[to]>dist[f]+distmap[f][to]||
(dist[to]==dist[f]+distmap[f][to]&&time[to]>time[f]+timemap[f][to])){
dist[to]=dist[f]+distmap[f][to];
time[to]=time[f]+timemap[f][to];
route[to]=route[f];
pq.push(Vertex{to,dist[to]});
}
}
}
resDistRoute=route[ed];
mindist=dist[ed];
}
void dijkstra2(int st,int ed){
vector<bool> vis(n,false);
vector<int> time(n,INF);
vector<vector<int> > route(n);
priority_queue<Vertex> pq;
time[st]=0;
pq.push(Vertex{st,0});
while(!pq.empty()){
int f=pq.top().x;
pq.pop();
if(vis[f]) continue;
vis[f]=true;
route[f].push_back(f);
if(f==ed) break;
for(int i=0;i<edge[f].size();i++){
int to=edge[f][i];
if(vis[to]) continue;
if(time[to]>time[f]+timemap[f][to]||
(time[to]==time[f]+timemap[f][to]&&route[to].size()>route[f].size())
){
time[to]=time[f]+timemap[f][to];
route[to]=route[f];
pq.push(Vertex{to,time[to]});
}
}
}
mintime=time[ed];
resTimeRoute=route[ed];
}
void ppath(vector<int> path){
for(int i=0;i<path.size();i++)
printf(" %d%s",path[i],i==path.size()-1?"\n":" ->");
}
int main(){
// freopen("1.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
int v1,v2,o,l,t;
scanf("%d%d%d%d%d",&v1,&v2,&o,&l,&t);
buildEdge(v1,v2,l,t);
if(o==0) buildEdge(v2,v1,l,t);
}
int s,e;
scanf("%d%d",&s,&e);
dijkstra1(s,e);
dijkstra2(s,e);
if(resDistRoute==resTimeRoute){
printf("Distance = %d; Time = %d:",mindist,mintime);
ppath(resDistRoute);
}else{
printf("Distance = %d:",mindist);
ppath(resDistRoute);
printf("Time = %d:",mintime);
ppath(resTimeRoute);
}
return 0;
}
普通dijkstra+dfs遍历pre
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#define INF 0x3fffffff
using namespace std;
int n,m,a,b,oneway,templen,temptime;
int tm[520][520],dist[520][520];
int d[520],t[520];
bool vis[520];
vector<int> timepre[520],distpre[520];
vector<int> tempv,distres,timeres;
int mintime2dist=INF,mindist2time=INF;
void dfs1(int s,int e){
if(s==e){
int sum=0;
tempv.push_back(s);
for(int i=tempv.size()-1;i>0;i--){
sum+=tm[tempv[i]][tempv[i-1]];
}
if(sum<mintime2dist){
distres=tempv;
mintime2dist=sum;
}
tempv.pop_back();
return;
}
for(int i=0;i<distpre[s].size();i++){
tempv.push_back(s);
dfs1(distpre[s][i],e);
tempv.pop_back();
}
}
void dfs2(int s,int e){
if(s==e){
int sum=0;
tempv.push_back(s);
if(tempv.size()<mindist2time){
timeres=tempv;
mindist2time=tempv.size();
}
tempv.pop_back();
return;
}
for(int i=0;i<timepre[s].size();i++){
tempv.push_back(s);
dfs2(timepre[s][i],e);
tempv.pop_back();
}
}
void dijkstra1(int s){//shortest
fill(d,d+520,INF);
fill(vis,vis+520,false);
d[s]=0;
for(int i=0;i<n;i++){
int u=-1,MIN=INF;
for(int j=0;j<n;j++){
if(d[j]<MIN&&vis[j]==false){
MIN=d[j];u=j;
}
}
vis[u]=true;
if(u==-1) return;
for(int j=0;j<n;j++){
if(vis[j]==false&&dist[u][j]<INF){
if(d[j]>d[u]+dist[u][j]){
d[j]=d[u]+dist[u][j];
distpre[j].clear();
distpre[j].push_back(u);
}else if(d[j]==d[u]+dist[u][j]){
distpre[j].push_back(u);
}
}
}
}
}
void dijkstra2(int s){//fastest
fill(t,t+520,INF);
fill(vis,vis+520,false);
t[s]=0;
for(int i=0;i<n;i++){
int u=-1,MIN=INF;
for(int j=0;j<n;j++){
if(t[j]<MIN&&vis[j]==false){
MIN=t[j];u=j;
}
}
vis[u]=true;
if(u==-1) return;
for(int j=0;j<n;j++){
if(vis[j]==false&&tm[u][j]<INF){
if(t[j]>t[u]+tm[u][j]){
t[j]=t[u]+tm[u][j];
timepre[j].clear();
timepre[j].push_back(u);
}else if(t[j]==t[u]+tm[u][j]){
timepre[j].push_back(u);
}
}
}
}
}
int main(){
// freopen("1.txt","r",stdin);
scanf("%d%d",&n,&m);
fill(tm[0],tm[0]+520*520,INF);
fill(dist[0],dist[0]+520*520,INF);
for(int i=0;i<m;i++){
scanf("%d%d%d%d%d",&a,&b,&oneway,&templen,&temptime);
if(oneway==0){
tm[b][a]=min(tm[b][a],temptime);
dist[b][a]=min(dist[b][a],templen);
}
tm[a][b]=min(tm[a][b],temptime);
dist[a][b]=min(dist[a][b],templen);
}
int s,e;
scanf("%d%d",&s,&e);
dijkstra1(s);//shortest
dfs1(e,s);
tempv.clear();
dijkstra2(s);//fastest
dfs2(e,s);
reverse(distres.begin(),distres.end());
reverse(timeres.begin(),timeres.end());
int restime=0,resdist=0;
for(int i=0;i<distres.size()-1;i++){
resdist+=dist[distres[i]][distres[i+1]];
}
for(int i=0;i<timeres.size()-1;i++){
restime+=tm[timeres[i]][timeres[i+1]];
}
if(timeres==distres){
printf("Distance = %d; Time = %d:",resdist,restime);
for(int i=0;i<distres.size();i++){
printf(" %d",distres[i]);
if(i!=distres.size()-1) printf(" ->");
}
}else{
printf("Distance = %d:",resdist);
for(int i=0;i<distres.size();i++){
printf(" %d",distres[i]);
if(i!=distres.size()-1) printf(" ->");
}
printf("\nTime = %d:",restime);
for(int i=0;i<timeres.size();i++){
printf(" %d",timeres[i]);
if(i!=timeres.size()-1) printf(" ->");
}
}
}