A1111 Online Map (30分)(最短路径、Dijkstra+DFS)
一、技术总结
- 关于最短路径的问题,可以将问题化简,为两个部分,一个是单独使用Dijkstra求最短路径,然后再使用DFS进行第二判定条件再选出合适的路径;
- 其中推荐使用邻接表来存储图的信息,至于其他边权可以使用二维数组进行存储,如果点权直接使用结构体进行存储信息;
- 如果有多个判定条件,应该分别使用Dijkstra遍历图,被放在一个里面进行遍历;
二、参考代码
#include<iostream>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 505;
const int INF = 10000000;
vector<int> G[maxn];
vector<int> preW[maxn], preT[maxn];
vector<int> tempPathW, tempPathT, pathW, pathT;
int w[maxn][maxn], t[maxn][maxn];
int d[maxn], c[maxn];
bool visW[maxn] = {false}, visT[maxn] = {false};
int optValueT = INF, optValueW = INF;
int n, m, st, ed;
void DijkstraW(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(visW[j] == false && d[j] < MIN){
u = j;
MIN = d[j];
}
}
if(u == -1) return;
visW[u] = true;
for(int j = 0; j < G[u].size(); j++){
int v = G[u][j], l = w[u][v];
if(visW[v] == false){
if(d[u] + l < d[v]){
d[v] = d[u] + l;
preW[v].clear();
preW[v].push_back(u);
}else if(d[u] + l == d[v]){
preW[v].push_back(u);
}
}
}
}
}
void DijkstraT(int s){
fill(c, c+maxn, INF);
c[s] = 0;
for(int i = 0; i < n; i++){
int u = -1, MIN = INF;
for(int j = 0; j < n; j++){
if(visT[j] == false && c[j] < MIN){
u = j;
MIN= d[j];
}
}
if(u == -1) return;
visT[u] = true;
for(int j = 0; j < G[u].size(); j++){
int v = G[u][j], ti = t[u][v];
if(visT[v] == false){
if(c[u] + ti < c[v]){
c[v] = c[u] + ti;
preT[v].clear();
preT[v].push_back(u);
}else if(c[u] + ti == c[v]){
preT[v].push_back(u);
}
}
}
}
}
void DFSW(int d){
if(d == st){
tempPathW.push_back(d);
int value = 0;
for(int i = tempPathW.size() - 1; i > 0; i--){
int id = tempPathW[i], next = tempPathW[i-1];
value += t[id][next];
}
if(value < optValueW){
optValueW = value;
pathW = tempPathW;
}
tempPathW.pop_back();
return;
}
tempPathW.push_back(d);
for(int i = 0; i < preW[d].size(); i++){
DFSW(preW[d][i]);
}
tempPathW.pop_back();
}
void DFST(int d){
if(d == st){
tempPathT.push_back(d);
if(tempPathT.size() < optValueT){
optValueT = tempPathT.size();
pathT = tempPathT;
}
tempPathT.pop_back();
return;
}
tempPathT.push_back(d);
for(int i = 0; i < preT[d].size(); i++){
DFST(preT[d][i]);
}
tempPathT.pop_back();
}
int main(){
cin >> n >> m;
int v1, v2, flag, length, time;
for(int i = 0; i < m; i++){
scanf("%d%d%d%d%d", &v1, &v2, &flag, &length, &time);
if(flag == 1){
G[v1].push_back(v2);
w[v1][v2] = length, t[v1][v2] = time;
}else{
G[v1].push_back(v2);
G[v2].push_back(v1);
w[v1][v2] = length, t[v1][v2] = time;
w[v2][v1] = length, t[v2][v1] = time;
}
}
cin >> st >> ed;
DijkstraW(st);
DijkstraT(st);
DFSW(ed);
DFST(ed);
if(pathT == pathW){
printf("Distance = %d; Time = %d: ", d[ed], c[ed]);
for(int i = pathW.size() - 1; i >= 0; i--){
printf("%d", pathW[i]);
if(i != 0) printf(" -> ");
}
}else{
printf("Distance = %d: ", d[ed]);
for(int i = pathW.size() - 1; i >= 0; i--){
printf("%d", pathW[i]);
if(i != 0) printf(" -> ");
if(i == 0) printf("\n");
}
printf("Time = %d: ", c[ed]);
for(int i = pathT.size() - 1; i >= 0; i--){
printf("%d", pathT[i]);
if(i != 0) printf(" -> ");
}
}
return 0;
}
作者:睿晞
身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
曾有一个业界大牛说过这样一段话,送给大家:
“华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.