1 条题解

  • 0
    @ 2025-1-10 8:48:05

    提供一种比较新的思路。

    首先套路地建原图和反图,计算起点到每个点的最短路 aia_i 和每个点到终点的最短路 bib_i

    然后我们要找 ai+bj+kija_i+b_j+k|i-j| 的最小值。

    这里可以考虑建分层图,总共 33 层,起点和终点独立,起点向第一层每个点 p1,ip_{1,i} 连有向边,权值为 aia_i,第一层每个点 p1,ip_{1,i} 向第二层对应点 p2,ip_{2,i} 连权为 00 的有向边,第二层相邻点 p2,i,p2,i+1(in1)p_{2,i},p_{2,i+1}(i\le n-1) 间连权为 kk 的无向边,第二层每个点 p2,ip_{2,i} 向第三层对应点 p3,ip_{3,i} 连权为 00 的有向边,第三层每个点 p3,ip_{3,i} 向终点连权为 bib_i 的有向边。

    int64_t n, m, k;
    cin >> n >> m >> k;
    Graph graph1(n), graph2(n);
    for (int64_t i = 0; i < m; i++) {
      int64_t u, v, w;
      cin >> u >> v >> w;
      u--, v--;
      graph1[u].emplace_back(v, w);
      graph2[v].emplace_back(u, w);
    }
    auto dist1 = dijkstra(graph1, 0);
    auto dist2 = dijkstra(graph2, n - 1);
    Graph graph3(3 * n);
    auto get_p = [&](int64_t i, int64_t j) -> int64_t { return n * i + j; };
    int64_t tar = get_p(2, n - 1);
    graph3[0].emplace_back(tar, dist1[n - 1]);
    for (int64_t i = 1; i < n - 1; ++i) {
      graph3[0].emplace_back(i, dist1[i]);
      graph3[get_p(2, i)].emplace_back(tar, dist2[i]);
      graph3[i].emplace_back(get_p(1, i), 0);
      graph3[get_p(1, i)].emplace_back(get_p(2, i), 0);
      if (i != 1) {
        graph3[get_p(1, i)].emplace_back(get_p(1, i - 1), k);
        graph3[get_p(1, i - 1)].emplace_back(get_p(1, i), k);
      }
    }
    auto dist3 = dijkstra(graph3, 0);
    cout << (dist3[tar] == INF ? -1 : dist3[tar]) << '\n';
    
  • 1

信息

ID
17
时间
1000ms
内存
256MiB
难度
10
标签
(无)
递交数
7
已通过
2
上传者