题意
给出n条线路,输入k组起点,终点,要求输出最优路径的信息。
最优路径:经过的站点最少,若站点数量相同则选择转乘最少的。
思路
看到题目就知道是比较繁琐的一题。
- 最优路径选取:dfs 选择最优路径,有两种方法:一种是记录所有的路径,最后再遍历选出最优的路径;一种是直接选取,这里我选择的是第二种方法。
- 输出最优路径信息是最繁琐的过程。
Sample Input:
4
7 1001 3212 1003 1204 1005 1306 7797
9 9988 2333 1204 2006 2005 2004 2003 2302 2001
13 3011 3812 3013 3001 1306 3003 2333 3066 3212 3008 2302 3010 3011
4 6666 8432 4011 1306
3
3011 3013
6666 2001
2004 3001
Sample Output:
2
Take Line#3 from 3011 to 3013.
10
Take Line#4 from 6666 to 1306.
Take Line#3 from 1306 to 2302.
Take Line#2 from 2302 to 2001.
6
Take Line#2 from 2004 to 1204.
Take Line#1 from 1204 to 1306.
Take Line#3 from 1306 to 3001.
#include "bits/stdc++.h"
using namespace std;
int a, b;
const int N = 10000;
vector<int> links[N];
int G[N][N];
int getLineId(int from, int to){
return G[from][to];
}
vector<int> ans,temp;
int vis[N];
int cntTransfers(vector<int>& path){
int pre = -1;
int res = 0;
for(int i=1;i<path.size();i++){
int id = getLineId(path[i],path[i-1]);
if (id != pre) pre = id, res ++;
}
return res;
}
void dfs(int id){
if (vis[id] || (!ans.empty() && ans.size() <= temp.size())) return;
temp.push_back(id);
if (id == b ) {
if (
ans.empty()
|| temp.size() < ans.size()
|| (temp.size() == ans.size() && cntTransfers(temp)<cntTransfers(ans))
) ans = vector<int>(temp);
temp.pop_back();
return;
}
vis[id] = 1;
for(int t:links[id]) dfs(t);
temp.pop_back();
vis[id] = 0;
}
void show(){
int line = -1; int from = ans[0];
for(int i=1;i<ans.size();i++){
if (line == -1) {
line = getLineId(ans[i],ans[i-1]);
} else if (getLineId(ans[i],ans[i-1]) != line ){
printf("Take Line#%d from %04d to %04d.\n",line,from,ans[i-1]);
line = getLineId(ans[i],ans[i-1]);
from = ans[i-1];
}
if (i == ans.size() -1)
printf("Take Line#%d from %04d to %04d.\n",line,from,ans[i]);
}
}
int main(){
// freopen("input.txt","r",stdin);
int n; cin >> n;
for (int i = 0; i < n; ++i) {
int m; scanf("%d",&m); vector<int> line(m);
for (int j = 0; j < m; ++j) scanf("%d",&line[j]);
for (int j = 1; j < m; ++j) {
links[line[j]].push_back(line[j-1]);
links[line[j-1]].push_back(line[j]);
G[line[j]][line[j-1]] = G[line[j-1]][line[j]] = i + 1;
}
}
int k; cin >> k;
for (int i = 0; i < k; ++i) {
scanf("%d%d",&a,&b);
temp.clear(); ans.clear();
dfs(a);
cout << ans.size()-1 << endl;
show();
}
}