很明显 对于无权图求最短路径,宽度优先搜索是比较好的办法 最后通过回溯将最短路径输出,
可以用 一个 unorder map存储路径 如 A*10000+B;
#include <bits/stdc++.h>
using namespace std;
const int Max=10005;
vector<int> graph[Max],past[Max],path;
int N,M,K,start,cEnd;
int dis[Max];
void BFS(){
for (int i = 0; i < Max; ++i) {
dis[i]=INT_MAX;
past[i].clear();
}
queue<int> q;
dis[start]=0;
q.push(start);
while (!q.empty()){
int p=q.front();
q.pop();
if (dis[p]>dis[cEnd])
continue;
for(int i:graph[p]){
if (dis[i]>=dis[p]+1){
if (dis[i]==INT_MAX)
q.push(i);
dis[i]=dis[p]+1;
if (dis[i]>dis[p]+1)
past[i].clear();
past[i].push_back(p);
}
}
}
}
vector<pair<int,int>> trans;//值代表路径名,建代表换乘站名;
unordered_map<int,int> mp;
void DFS(int v){
path.push_back(v);
if (v==start){
vector<pair<int,int>> currentTrans={{start,-1}};
for (int i = path.size()-2; i > 0 ; --i) {
if (mp[path[i-1]*10000+path[i]]!=mp[path[i]*10000+path[i+1]])
currentTrans.push_back({path[i],mp[path[i]*10000+path[i+1]]});
}
currentTrans.push_back({cEnd,mp[path[1]*10000+cEnd]});
if (trans.empty() || currentTrans.size()<trans.size())
trans=currentTrans;
}
for(int i:past[v])
DFS(i);
path.pop_back();
}
int main(){
cin>>N;
for (int i = 1; i <=N ; ++i) {
cin>>M>>start;
for (int j = 1; j <M ; ++j,start=cEnd) {
cin>>cEnd;
mp.insert({start*10000+cEnd,i});
mp.insert({cEnd*10000+start,i});
graph[start].push_back(cEnd);
graph[cEnd].push_back(start);
}
}
cin>>K;
while (K--){
cin>>start>>cEnd;
BFS();
path.clear();
trans.clear();
DFS(cEnd);
printf("%d\n",dis[cEnd]);
for (int i = 1; i < trans.size(); ++i) {
printf("Take Line#%d from %04d to %04d.\n",trans[i].second,trans[i-1].first,trans[i].first);
}
}
return 0;
}