1131. Subway Map (30) dfs

简介: In the big cities, the subway systems always look so complex to the visitors.

In the big cities, the subway systems always look so complex to the visitors. To give you some sense, the following figure shows the map of Beijing subway. Now you are supposed to help people with your computer skills! Given the starting position of your user, your task is to find the quickest way to his/her destination.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (< =100), the number of subway lines. Then N lines follow, with the i-th (i = 1, …, N) line describes the i-th subway line in the format:

M S[1] S[2] … S[M]

where M (<= 100) is the number of stops, and S[i]’s (i = 1, … M) are the indices of the stations (the indices are 4-digit numbers from 0000 to 9999) along the line. It is guaranteed that the stations are given in the correct order – that is, the train travels between S[i] and S[i+1] (i = 1, …, M-1) without any stop.

Note: It is possible to have loops, but not self-loop (no train starts from S and stops at S without passing through another station). Each station interval belongs to a unique subway line. Although the lines may cross each other at some stations (so called “transfer stations”), no station can be the conjunction of more than 5 lines.

After the description of the subway, another positive integer K (<= 10) is given. Then K lines follow, each gives a query from your user: the two indices as the starting station and the destination, respectively.

The following figure shows the sample map.

Note: It is guaranteed that all the stations are reachable, and all the queries consist of legal station numbers.

Output Specification:

For each query, first print in a line the minimum number of stops. Then you are supposed to show the optimal path in a friendly format as the following:

Take Line#X1 from S1 to S2.
Take Line#X2 from S2 to S3.
……
where Xi’s are the line numbers and Si’s are the station indices. Note: Besides the starting and ending stations, only the transfer stations shall be printed.

If the quickest path is not unique, output the one with the minimum number of transfers, which is guaranteed to be unique.

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.
不会写 来源

/*
 minCnt-中途经停的最少的站  minTransfer-需要换乘的最小次数

 可以这样计算出一条线路的换乘次数:
 在line[10000][10000]的数组中保存每两个相邻站中间的线路是几号线~
 从头到尾遍历最终保存的路径,preLine为前一小段的线路编号,如果当前的结点和前一个结点组成的这条路的线路编号和preLine不同,说明有一个换乘,就将cnt+1,
 最后遍历完累加的cnt即是换乘的次数~

 可以这样计算出一条线路中途停站的次数:
 在dfs的时候有个变量cnt,表示当前路线是所需乘的第几个站,
 每次dfs时候将cnt+1表示向下遍历一层~
 cnt就是当前中途停站的次数~

 可以这样输出结果:
 和计算线路换乘次数的思路一样,每当preLine和当前Line值不同的时候就输出一句话~
 保存preTransfer表示上一个换乘站
 最后不要忘记输出preTransfer和最后一个站之间的路即使最后一个站并不是换乘站
 */
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> v(10000);
int line[10000][10000], visit[10000], minCnt, minTransfer, start, end1;
vector<int> path, tempPath;
int transferCnt(vector<int> a) {
    int cnt = -1, preLine = 0;
    for (int i = 1; i < a.size(); i++) {
        if (line[a[i-1]][a[i]] != preLine) cnt++;
        preLine = line[a[i-1]][a[i]];
    }
    return cnt;
}
void dfs(int node, int cnt) {
    if (node == end1 && (cnt < minCnt || (cnt == minCnt && transferCnt(tempPath) < minTransfer))) {
        minCnt = cnt;
        minTransfer = transferCnt(tempPath);
        path = tempPath;
    }
    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);
            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);
        for (int j = 1; j < m; j++) {
            scanf("%d", &temp);
            v[pre].push_back(temp);
            v[temp].push_back(pre);
            line[pre][temp] = line[temp][pre] = i + 1;
            pre = temp;
        }
    }
    scanf("%d", &k);
    for (int i = 0; i < k; i++) {
        scanf("%d%d", &start, &end1);
        minCnt = 99999;
        minTransfer = 99999;
        tempPath.clear();
        tempPath.push_back(start);
        visit[start] = 1;
        dfs(start, 0);
        visit[start] = 0;
        printf("%d\n", minCnt);
        int preLine = 0, preTransfer = start;
        for (int j = 1; j < path.size(); j++) {
            if (line[path[j-1]][path[j]] != preLine) {
                if (preLine != 0) printf("Take Line#%d from %04d to %04d.\n", preLine, preTransfer, path[j-1]);
                preLine = line[path[j-1]][path[j]];
                preTransfer = path[j-1];
            }
        }
        printf("Take Line#%d from %04d to %04d.\n", preLine, preTransfer, end1);
    }
    return 0;
}
目录
相关文章
|
7月前
|
机器学习/深度学习 人工智能 定位技术
|
7月前
遍历图(dfs)
遍历图(dfs)
18 0
|
10月前
DFS:生日蛋糕
DFS:生日蛋糕
|
10月前
|
定位技术
DFS:踏青
DFS:踏青
CF1286B.Numbers on Tree(构造 dfs)
CF1286B.Numbers on Tree(构造 dfs)
70 0
CF708C-Andryusha and Colored Balloons(dfs)
CF708C-Andryusha and Colored Balloons(dfs)
75 0
dfs
题目描述 你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示: ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。 由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。 例如上图中的海域未来会变成如下样子: ....... ....... ....... ....... ....#.. ......
|
算法
迭代加深(DFS)
复习acwing算法提高课的内容,本篇为讲解算法:迭代加深,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。
112 0
迭代加深(DFS)
计蒜客-1217 马走日(dfs)
马在中国象棋以日字形规则移动。
174 0
【LeetCode133】克隆图(dfs和unordered_map)
节点数不超过 100 。 每个节点值 Node.val 都是唯一的,1 <= Node.val <= 100。
86 0
【LeetCode133】克隆图(dfs和unordered_map)