#include<iostream> #include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> #include<algorithm> #include<map> #include<vector> #include<queue> #include<unordered_map> using namespace std; int visit[10000],minCnt,minTransfer; vector<vector<int>> v(10000); vector<int> path,tempPath;//路径vector int start,end1;//起点 终点 unordered_map<int,int> line; /*unordered_map<int,int>line存储两个结点的边所属的路线 假设边两端为a到b,line的键为a*10000+b,值为这条边所属的路线*/ int transferCnt(vector<int> a){//传入临时路径 int cnt=-1,preLine=0; for(int i=1;i<a.size();i++){ if(line[a[i-1]*10000+a[i]] != preLine) cnt++;//换乘数cnt+1 preLine=line[a[i-1]*10000+a[i]]; } return cnt;//输出换乘数 } void dfs(int node,int cnt){ //cnt为换乘数 if(node==end1&&(cnt<minCnt||(cnt ==minCnt&& transferCnt(tempPath) <minTransfer))) { minCnt=cnt;//更新cnt minTransfer=transferCnt(tempPath);//更新最小换乘次数 path=tempPath;//更新路径vector } if(node == end1) return;//边界 for(int i=0;i<v[node].size();i++){ if(visit[v[node][i]] == 0){ visit[v[node][i]]=1;//加锁 tempPath.push_back(v[node][i]); dfs( v[node][i] ,cnt+1); //cnt+1,进入下一层dfs visit[v[node][i] ]=0;//解锁 tempPath.pop_back(); } } } int main(){ int n,m,k,pre,temp; scanf("%d",&n);//地铁路线数 for(int i=0;i<n;i++){ scanf("%d%d",&m,&pre);//pre为m线路的首站 for(int j=1;j<m;j++){//for循环剩下的m-1个站 scanf("%d",&temp); v[pre].push_back(temp); //首站为pre的线路(vector里)加上temp站 v[temp].push_back(pre); //temp站的vector里加入首站(pre) line[pre*10000+temp]=line[temp*10000+pre]=i+1; //pre到temp的线路=temp到pre的线路+1 pre=temp;//首站为temp } } scanf("%d",&k);//k次查询 for(int i=0;i<k;i++){ scanf("%d%d",&start,&end1); //查询start站到end1站 //minCnt为最小换乘数,minTransfer为换乘站 minCnt=99999,minTransfer=99999;//初始化 tempPath.clear(); tempPath.push_back(start);//把start压入临时路径vector visit[start]=1; //加锁 dfs(start,0); //递归DFS!!!!!!!!! visit[start]=0; //解锁 //以下为output printf("%d\n",minCnt);//起点&终点之间的min站数 int preLine=0,preTransfer=start; for(int j=1;j<path.size() ; j++){ if(line[path[j-1]*10000+path[j]] != preLine){ if(preLine != 0) //每当line和preline不等则输出这句话 printf("Take Line#%d from %04d to %04d.\n", preLine,preTransfer,path[j-1] ); preLine=line[path[j-1]*10000+path[j]];//更新上一条线路号 preTransfer = path[j-1];//更新上一个换乘站 } } printf("Take Line#%d from %04d to %04d.\n", preLine,preTransfer,end1);//输出最后一小截线路 //preLine路线 从preTransfer站到end1站 } system("pause"); return 0; }