• [2018南京预赛]Magical Girl Haze


    一、题面

    样例输入:

    1
    5 6 1
    1 2 2
    1 3 4
    2 4 3
    3 4 1
    3 5 6
    4 5 2

    样例输出:

    3

    二、思路

    关键词:分层BFS

    考试时觉得题干意思很清晰——求可将k条边赋值为0的最短路。起初几个思路正确性均存疑,后来觉得应该要DP于是决定滞后了。。。

    正解——分层BFS,个人认为思路与DP有些许相像,同时记录节点及当前已赋值为0的边数,则在跑最短路时(这里用的SPFA),可选择是否将该条边赋值为0,当且仅当已选边<k。

    三、代码

     1 #include <cstdio>
     2 #include <cstring> 
     3 
     4 #define MAXN 100005
     5 #define MAXM 200005
     6 #define MAXK 15
     7 #define INF 0x3f3f3f3f    
     8 
     9 int T, n, m, k, u, v, w, o, h[MAXN], d[MAXN][MAXK], vis[MAXN][MAXK];
    10 
    11 struct node {
    12     int n, k;
    13 } q[MAXN];
    14 
    15 struct edge {
    16     int v, next, w;
    17 } e[MAXM];
    18 
    19 void add(int u, int v, int w) {
    20     o++, e[o] = (edge) {v, h[u], w}, h[u] = o;
    21 }
    22 
    23 int spfa() {
    24     int head = 1, tail = 2;
    25     memset(d, INF, sizeof(d)), memset(vis, 0, sizeof(vis));
    26     q[head] = (node) {1, 0}, d[1][0] = 0, vis[1][0] = 1;
    27     while (head != tail) {
    28         node o = q[head];
    29         vis[o.n][o.k] = 0;
    30         for (int x = h[o.n]; x; x = e[x].next) {
    31             int v = e[x].v;
    32             if (d[v][o.k] > d[o.n][o.k] + e[x].w) {
    33                 d[v][o.k] = d[o.n][o.k] + e[x].w;
    34                 if (!vis[v][o.k]) vis[v][o.k] = 1, q[tail++] = (node) {v, o.k};
    35             }
    36             if (o.k < k) {
    37                 if (d[v][o.k + 1] > d[o.n][o.k]) {
    38                     d[v][o.k + 1] = d[o.n][o.k];
    39                     if (!vis[v][o.k + 1]) vis[v][o.k + 1] = 1, q[tail++] = (node) {v, o.k + 1};
    40                 }
    41             }
    42         }
    43         head++;
    44     }
    45     return d[n][k];
    46 }
    47 
    48 int main() {
    49     scanf("%d", &T);
    50     for (int i = 1; i <= T; i++) {
    51         o = 0, memset(h, 0, sizeof(h));
    52         scanf("%d %d %d", &n, &m, &k);
    53         for (int j = 1; j <= m; j++) scanf("%d %d %d", &u, &v, &w), add(u, v, w);
    54         printf("%d
    ", spfa()); 
    55     }
    56     return 0;
    57 }

    多个子问题着重考虑各种初始化!

  • 相关阅读:
    UML中常用的类图元素介绍
    灵魂架构师论坛 正在崛起
    什么是模式,什么是框架
    RPG Maker XP
    php常用HEADER头记录
    PHP MYSQLI扩展库面向对象编程 数据库连接 例子
    PHP 通过MYSQL扩展库 连接MYSQL例子
    MYSQL 数据库相关操作总结
    MYSQL 客户端控制台 中文乱码
    PHP 安全编程慢慢总结
  • 原文地址:https://www.cnblogs.com/jinkun113/p/9579900.html
Copyright © 2020-2023  润新知