• `Algorithm-Solution` `AcWing` 920. 最优乘车


    link

    Solution

    This question is quite abstract if you not transform it to a graph.
    The notion Bus-Transfer is a little awkward, so we use Bus-Total which is one greater than the former. (e.g., we take buses A , B , C A, B, C A,B,C, then Bus-Total = Bus-Transfer + 1 = 3)

    The route of a bus has at most n n n stations.

    There is an important point that a route a → b → c a\to b\to c abc (because the bus is One-Directional), so a a a can arrive to b b b but inverse is not.


    If we handle it in a brute direct way, D i s t [ a ] [ b ] Dist[ a][ b] Dist[a][b] means the minimal Bus-Total from a a a to b b b.
    If we are currently at Bus-i, then D i s t [ a ] [ b ] Dist[a][b] Dist[a][b] means the minimal Bus-Total from a a a to b b b under using those Buses 0, ..., i-1.
    Suppose the route of current Bus-i is a 1 , a 2 , a 3 , a 4 a1, a2, a3, a4 a1,a2,a3,a4, it means a i ai ai can arrive to a j aj aj where j > i j > i j>i.
    so for every a i , a j ai, aj ai,aj, update x → a i − a j → y x \to ai - aj \to y xaiajy Dist[ x][ y] = min( self, Dist[ x][ ai] + 1 + Dist[ aj][ y])

    void __Solve( int _test_id){
        ( void)_test_id;
        //--
        int n, m;
        cin >> m >> n;
        getchar();
        memset( D, 0x3F, sizeof( D));
        for( int i = 0; i < m; ++i){
            string s;
            getline( cin, s);
            stringstream ss( s);
            int a;
            M = 0;
            while( ss >> a){
                -- a;
                A[ M ++] = a;
            }
            for( int j = 0; j < M - 1; ++j){
                for( int z = j + 1; z < M; ++z){
                    int a = A[ j], b = A[ z];
                    for( int p = 0; p < n; ++p){
                        for( int s = 0; s < n; ++s){
                            int l = D[ p][ a];
                            int r = D[ b][ s];
                            if( p == a){ l = 0;}
                            if( s == b){ r = 0;}
                            D[ p][ s] = min( D[ p][ s], l + r + 1);
                        }
                    }
                }
            }
            for( int j = 0; j < M - 1; ++j){
                for( int z = j + 1; z < M; ++z){
                    D[ A[ j]][ A[ z]] = 1;
                }
            }
        }
        if( D[ 0][ n - 1] > m){
            cout << "NO";
            return;
        }
        cout << D[ 0][ n - 1] - 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    But this is Out-Of-Time O ( n 4 ∗ m ) O(n^4 * m) O(n4m)


    To transform a graph question into a specific graph is vital, because graph-question is usually very abstract, hard to comprehend.

    First step:
    We consider what information a route of a bus a 1 , a 2 , a 3 , a 4 a1, a2, a3, a4 a1,a2,a3,a4 expresses.
    The all meanings of such a route is that, a i ai ai can reach a j aj aj where j > i j > i j>i.
    So suppose we have a directed unweighted graph G, then this route shows that there is a edge from a i ai ai to a j aj aj.
    Conversely, for any edge a → b a \to b ab in G, it implies that there has a bus that could take a a a to b b b.

    Second step:
    Then, we consider the meaning of Bus-Transfer.
    Two routes of Bus( a , b a,b a,b) are a 1 , . . . , a 5 , a 6 , . . . a1, ..., a5, a6, ... a1,...,a5,a6,... and b 1 , . . . , b 5 , b 6 , . . . b1, ..., b5, b6, ... b1,...,b5,b6,... (where a 5 = b 5 a5 = b5 a5=b5)
    If we currently at Bus-a, and get off at a 5 a_5 a5 then we can get on Bus-b at b 5 b_5 b5.
    The essence of Bus-Transfer is actually a point which is contained by two routes.
    The counterpart of this notion to the graph is:

    • a i ai ai (where i ≤ 5 i \leq 5 i5) can reach b j bj bj (where j ≥ 5 j \geq 5 j5)
    • b i bi bi (where i ≤ 5 i \leq 5 i5) can reach a j aj aj (where j ≥ 5 j \geq 5 j5)

    For the graph G constructed by First-Step rule, we found G G G has already possess the property of Bus-Transfer. (because there are paths a i → a 5 → b j ai \to a5 \to bj aia5bj and b i → b 5 → a j bi \to b5 \to aj bib5aj where i < 5 , j > 5 i \lt 5, j \gt 5 i<5,j>5)
    So, we need not to add extra information to the graph at this step.

    Third Step:
    What is the meaning of minimal Bus-Total?
    In the graph, a path a → b → c a \to b \to c abc consists of two edges a → b a \to b ab and b → c b \to c bc means that, there is a bus can take a a a to b b b and a bus that take b b b to c c c. (these two buses maybe a same bus)
    So the choices of a → b a \to b ab correspond to several paths in the graph, a path is a scheme that take a a a to b b b, the length of the path (the count of edges) means the Bus-Total of this scheme.

    So, let all edges in the graph to have a weight 1 1 1, then find the minimal-path in the graph (it can be solved by BFS)

  • 相关阅读:
    如何压缩jpg图片的大小?可以一键压缩图片的软件有哪些?
    Linux环境phantomjs安装,使用,常见问题
    qt -tablewidget设置列可排序
    TensorFlow入门(十一、图的基本操作)
    已解决:Ubuntu系统开启电脑一直出现Boot Menu
    【JavaEE】MyBatis 动态SQL 使用讲解
    基于Android的学习生活交流APP计算机毕业设计源码
    node版本管理工具推荐
    WebSecurityConfigurerAdapter过时的替代方式
    Android 12.0 开启蓝牙状态栏即显示蓝牙图标
  • 原文地址:https://blog.csdn.net/qq_66485519/article/details/128134435