PAT甲级1131 Subway Map【dfs】【输出方案】

时间:2023-03-09 04:14:36
PAT甲级1131 Subway Map【dfs】【输出方案】

题目https://pintia.cn/problem-sets/994805342720868352/problems/994805347523346432

题意:

PAT甲级1131 Subway Map【dfs】【输出方案】

告诉你一个地铁线路图,站点都是用四位数来编号。

现在问你从某一起点到某一终点,经过站数最少的乘车方式是什么?要输出方案。

如果站数相同要输出换乘较少的。

思路:

首先肯定是搜索没有问题了。因为要输出方案,所以bfs不太方便存答案。很容易想到用dfs

比较麻烦的是输出方案的时候,线路相同的那些站都合并在同一个线路里了。那么我们就再维护一个乘车区间结构体。

如果当前走的边和当前答案最后一条边是同一个线路,就把答案中最后一个乘车区间的终点改为当前的点。

回溯的时候不仅要把vis数组恢复,还要把答案恢复成dfs之前的,所以用一个tmpans来记录一下本次dfs之前的答案。

 #include<cstdio>
#include<cstdlib>
#include<map>
#include<set>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stack>
#include<queue> #define inf 0x7fffffff
using namespace std;
typedef long long LL;
typedef pair<string, string> pr; struct station{
int to;
int line;
station(){
}
station(int _to, int _line){
to = _to;
line = _line;
}
}; struct mapnode{
vector<station>list;
}; struct segment{
int st, ed;
int line;
segment(){}
segment(int _st, int _ed, int _line)
{
st = _st;
ed = _ed;
line = _line;
}
}; struct Ans{
int len;
vector<segment>anslist; bool operator < (const Ans b)const{
if(len == b.len)
return anslist.size() < b.anslist.size();
return len < b.len;
}
}; const int maxn = 1e5 + ;
mapnode sta[maxn];
int n, k; Ans ans, nowans;
bool vis[maxn];
void dfs(int st, int ed)
{
if(st == ed){
if(nowans < ans)ans = nowans;
//return;
} if(ans < nowans)return; for(int i = ; i < sta[st].list.size(); i++){
int to = sta[st].list[i].to;
if(!vis[to]){
Ans tmpans = nowans;
nowans.len++;
if(sta[st].list[i].line == nowans.anslist.back().line){
nowans.anslist.back().ed = to;
}
else{
nowans.anslist.push_back(segment(st, to,sta[st].list[i].line));
} vis[to] = true;
dfs(to, ed);
vis[to] = false;
nowans = tmpans;
}
}
} void init()
{
memset(vis, , sizeof(vis));
nowans.anslist.clear();
nowans.len = ;
nowans.anslist.push_back(segment(-, -, -));
ans.anslist.clear();
ans.len = inf; } int main()
{
scanf("%d", &n);
for(int i = ; i <= n; i++){
int m;
scanf("%d", &m);
int prev;
scanf("%d", &prev);
for(int j = ; j < m; j++){
int to;
scanf("%d", &to);
sta[prev].list.push_back(station(to, i));
sta[to].list.push_back(station(prev, i));
prev = to;
}
} scanf("%d", &k);
while(k--){
int st, ed;
scanf("%d%d", &st, &ed);
init();
dfs(st, ed);
printf("%d\n", ans.len);
for(int i = ; i < ans.anslist.size(); i++){
printf("Take Line#%d from %04d to %04d.\n", ans.anslist[i].line, ans.anslist[i].st, ans.anslist[i].ed);
}
} return ;
}