• PTA 网红店打卡攻略(带权建图搜索)


    题目

    一个旅游景点,如果被带火了的话,就被称为“网红点”。大家来网红点游玩,俗称“打卡”。在各个网红点打卡的快(省)乐(钱)方法称为“攻略”。你的任务就是从一大堆攻略中,找出那个能在每个网红点打卡仅一次、并且路上花费最少的攻略。

    输入格式:

    首先第一行给出两个正整数:网红点的个数 N(1

    再下一行给出一个正整数 K,是待检验的攻略的数量。随后 K 行,每行给出一条待检攻略,格式为:

    n V1 V2 ⋯ Vn

    其中 n(≤200) 是攻略中的网红点数,Vi是路径上的网红点编号。这里假设你从家里出发,从 V
    1开始打卡,最后从Vn回家。

    输出格式:

    在第一行输出满足要求的攻略的个数。

    在第二行中,首先输出那个能在每个网红点打卡仅一次、并且路上花费最少的攻略的序号(从 1 开始),然后输出这个攻略的总路费,其间以一个空格分隔。如果这样的攻略不唯一,则输出序号最小的那个。

    题目保证至少存在一个有效攻略,并且总路费不超过 109

    • 输入样例:
    6 13
    0 5 2
    6 2 2
    6 0 1
    3 4 2
    1 5 2
    2 5 1
    3 1 1
    4 1 2
    1 6 1
    6 3 2
    1 2 1
    4 5 3
    2 0 2
    7
    6 5 1 4 3 6 2
    6 5 2 1 6 3 4
    8 6 2 1 6 3 4 5 2
    3 2 1 5
    6 6 1 3 4 5 2
    7 6 2 1 3 4 5 2
    6 5 2 1 4 3 6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 输出样例:
    3
    5 11
    
    • 1
    • 2

    样例说明:

    第 2、3、4、6 条都不满足攻略的基本要求,即不能做到从家里出发,在每个网红点打卡仅一次,且能回到家里。所以满足条件的攻略有 3 条。

    第 1 条攻略的总路费是:(0->5) 2 + (5->1) 2 + (1->4) 2 + (4->3) 2 + (3->6) 2 + (6->2) 2 + (2->0) 2 = 14;

    第 5 条攻略的总路费同理可算得:1 + 1 + 1 + 2 + 3 + 1 + 2 = 11,是一条更省钱的攻略;

    第 7 条攻略的总路费同理可算得:2 + 1 + 1 + 2 + 2 + 2 + 1 = 11,与第 5 条花费相同,但序号较大,所以不输出。

    题解

    #include 
    #include 
    #include 
    #include 
    using namespace std;
    
    const int N = 210;
    int n, m, idx;
    int h[N];
    int e[N * N];
    int ne[N * N];
    int w[N * N];
    int first;
    bool mry[N];
    int minVal =INT_MAX;
    long long minnum = 0;
    
    void add(int a, int b, int c) {
        e[idx] = b;
        w[idx] = c;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    
    int main() {
        memset(h, -1, sizeof(h));
        cin >> n >> m;
    
        while (m--) {
            int a, b, c;
            cin >> a >> b >> c;
            add(a, b, c);
            add(b, a, c);
        }
    
        int k;
        cin >> k;
        int kk = k;
    
        while (k--) {
            memset(mry, false, sizeof(mry));
            int tmin = 0;
            int nk,be,en;
            cin >>nk;
           
            int road[nk+1];
            for(int i=1;i<=nk;i++){
                cin >> road[i];
            }      
             if(nk!=n){
                continue;
            }
            be=road[1];
            en=road[nk];
            mry[be] = true;
            int last = be;
            bool bef = false, enf = false;
    
            for (int i = h[0]; i != -1; i = ne[i]) {
                int j = e[i];
                if (j == be) {
                    bef = true;
                    tmin += w[i];
                    break;
                }
            }
    
            for (int i = h[en]; i != -1; i = ne[i]) {
                int j = e[i];
                if (j == 0) {
                    enf = true;
                    tmin += w[i];
                    break;
                }
            }
    
            if (!(enf && bef)) {
                continue;
            }
    
            int finish = 0;
    
            for (int i = 2; i <= nk; i++) {
                bool flag = false;
                int temp = road[i];
    
                for (int j = h[last]; j != -1; j = ne[j]) {
                    int l = e[j];
    
                    if (l == temp && !mry[temp]) {
                        flag = true;
                        tmin += w[j];
                        mry[temp] = true;
                        finish++;
                        last = temp;
                        break;
                    }
                }
    
                if (!flag) {
                    break;
                }
            }
    
            if (finish == nk - 1) {
                minnum++;
                if (tmin < minVal) {
                    minVal = tmin;
                    first = kk - k;
                }
            }
        }
    
        cout << minnum << endl;
        cout << first << " " << minVal << endl;
    
        return 0;
    }
    
    
    • 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
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    思路

    这道题与汉米尔回路类似,仅需将静态链表设计为带权链表。然后依照同样的思路,先建图,后搜索并条件判断即可。

  • 相关阅读:
    SuperMap GIS基础软件天地图服务Q&A
    数据库基本知识
    Qt隐式共享机制
    Transformer-深度学习-台湾大学李宏毅-课程笔记
    spring框架限制接口是否要登录过才能访问
    什么是华为认证-Datacom数据通信工程师?
    PayPal账户遭大规模冻结!跨境卖家如何自救?
    WebGPU缓冲区更新最佳实践
    STM32MP157A驱动开发 | 03-usb host接口的使用(U盘 )
    btc钱包探索纪实
  • 原文地址:https://blog.csdn.net/qq_62235017/article/details/134287226