1111 Online Map
程序员文章站
2022-06-11 18:05:01
...
题目大意
给一张地图,两个结点中既有距离也有时间,有的单行有的双向,要求根据地图推荐两条路线:一条是最快到达路线,一条是最短距离的路线。 第一行给出两个整数N和M,表示地图中地点的个数和路径的条数。接下来的M行每一行给出:道路结点编号V1 道路结点编号V2 是否单行线 道路长度 所需时间 要求第一行输出最快到达时间Time和路径,第二行输出最短距离Distance和路径最短路径不唯一,输出最快的; 最快路径不唯一,输出经历节点最少的
思路解析
又是dijkstra + DFS,只不过需要分别做两次罢了。题目不难,要有耐心。还有one-way是单向路的意思,真长知识……示例代码
#include<iostream>
#include<vector>
#include<algorithm>
#define INF (~(0x1<<31))
using namespace std;
vector<vector<int>> gra(510, vector<int>(510,INF)), weight(510, vector<int>(510,INF));
int n, m, mind, mint, s, d;
vector<vector<int>> dijkstra(int v ,vector<vector<int>> Gra,int flag) {
vector<int> dist(510, INF);
vector<bool> visited(510,false);
vector<vector<int>> path(510);
dist[v] = 0;
for (int i = 0; i < n; i++) {
int min = INF,u = -1;
for (int j = 0; j < n; j++) {
if (!visited[j] && dist[j] < min) {
min = dist[j];
u = j;
}
}
visited[u] = true;
for (int j = 0; j < n; j++) {
if (!visited[j] && Gra[u][j] != INF) {
if (dist[u] + Gra[u][j] < dist[j]) {
dist[j] = dist[u] + Gra[u][j];
path[j].clear();
path[j].push_back(u);
}
else if (dist[u] + Gra[u][j] == dist[j]) {
path[j].push_back(u);
}
}
}
}
if (flag)
mind = dist[d];
else
mint = dist[d];
return path;
}
int mmin = INF;
vector<int> tempath, res;
void find_shortest(int s,int d,int sum,vector<vector<int>> path) {//s原点 d当前节点
tempath.push_back(d);
if (s == d) {//回到起点了
if (sum < mmin) {
mmin = sum;
res = tempath;
}
tempath.pop_back();
return;
}
for (int i = 0; i < path[d].size(); i++) {
int to = path[d][i];//前一个节点
find_shortest(s, to, sum + weight[to][d], path);
}
tempath.pop_back();
}
void find_fast(int s, int d, int deep, vector<vector<int>> path) {
tempath.push_back(d);
if (s == d) {
if (deep < mmin) {
mmin = deep;
res = tempath;
}
tempath.pop_back();
return;
}
for (int i = 0; i < path[d].size(); i++) {
int to = path[d][i];
find_fast(s, to, deep + 1, path);
}
tempath.pop_back();
}
void show(vector<int> res) {
for (int i = res.size()-2; i >= 0; i--) {
printf(" -> %d", res[i]);
}
printf("\n");
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++) {
int v1, v2, flag, length, time;
scanf("%d %d %d %d %d", &v1, &v2, &flag, &length, &time);
gra[v1][v2] = length;
weight[v1][v2] = time;
if (flag == 0) {
gra[v2][v1] = length;
weight[v2][v1] = time;
}
}
scanf("%d %d", &s, &d);
vector<vector<int>> distance = dijkstra(s, gra, true);
vector<vector<int>> time = dijkstra(s, weight, false);
find_shortest(s, d, 0, distance);
vector<int> temp1 = res;
mmin = INF;
res.clear();
find_fast(s, d, 1, time);
vector<int> temp2 = res;
bool flag = false;
if (temp1.size() != temp2.size()) {
flag = true;
}
else {
int i = 0;
for (i; i < temp1.size() && temp1[i] == temp2[i]; i++);
if (i != temp1.size()) {
flag = true;
}
}
if (flag) {
printf("Distance = %d: %d", mind, s);
show(temp1);
printf("Time = %d: %d", mint, s);
show(temp2);
}
else {
printf("Distance = %d; Time = %d: %d", mind, mint, s);
show(temp1);
}
return 0;
}