• 单源最短路的建图方式(复习总结)


    1129. 热浪 - AcWing题库

    模版题,复习最短路模版用

    1128. 信使 - AcWing题库

    哨兵送信的最短距离,取决于从起点到n个哨所的最长路径.求一遍最短路径后,选取最长的路径输出即可,如果有不能到达的则输出-1

    1127. 香甜的黄油 - AcWing题库

    通过最短路算法,枚举以每个牧场为中心,其他牧场的奶牛到该牧场到距离之和,取最小值,就可以得到本题的答案

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    constexpr int N = 5020;
    int h[N], e[N], ne[N], w[N], idx;
    int dist[N], n, p, t, cnt[N];
    bool st[N];
    
    typedef pair<int, int> PII;
    
    inline void add(int a, int b, int c) {
      e[++idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx;
    }
    
    inline int dijkstra(int s) {
      for (int i = 0; i <= p; i++) { st[i] = 0, dist[i] = 10010; }
      priority_queue<PII, vector<PII>, greater<PII>> q;
      q.push({0, s});
      dist[s] = 0;
    
      while (q.size()) {
        auto t = q.top(); q.pop();
        int ver = t.second, d = t.first;
        if (st[ver]) continue;
        st[ver] = 1;
    
        for (int i = h[ver]; i; i = ne[i]) {
          int j = e[i];
          if (dist[j] > d + w[i]) {
            dist[j] = d + w[i];
            if (!st[j]) q.push({dist[j], j});
          }
        }
      }
    
      int res = 0;
      for (int i = 1; i <= p; i++) {
        if (i == s) continue;
        res += cnt[i] * dist[i];
      }
    
      return res;
    }
    
    int main() {
      scanf("%d%d%d", &n, &p, &t);
      for (int i = 1; i <= n; i++) {
        int x; scanf("%d", &x);
        cnt[x]++;
      }
    
      while (t --) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
        add(b, a, c);
      }
    
      int res = 0x3f3f3f3f;
      for (int i = 1; i <= p; i++)
        res = min(res, dijkstra(i));
    
      printf("%d\n", res);
    
      return 0;
    }
    

    1126. 最小花费 - AcWing题库

    本题是以浮点数为边权的最短路问题,每条边权的值为val/(1-1.0*w[i]/100),直接求最短路即可

    920. 最优乘车 - AcWing题库

    本题给你若干条公交线路.

    对于同一条线路上的站点,我们可以直接让前面的站点和后面的站点连一条边,这样一来,路径长度-1就代表需要换乘的最少次数

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <sstream>
    #include <vector>
    using namespace std;
    
    typedef pair<int, int> PII;
    constexpr int N = 1010;
    int h[N], e[N], ne[N], idx;
    int dist[N], n, m;
    bool st[N];
    
    inline void add(int a, int b) {
      e[++idx] = b, ne[idx] = h[a], h[a] = idx;
    }
    
    char s[N];
    inline void build() {
      stringstream stream;
      stream << s;
      int a[N], t = 0;
      while (stream >> a[t]) t++;
    
      for (int i = 0; i < t; i++) 
        for (int j = i + 1; j < t; j++)
          add(a[i], a[j]);
    }
    
    inline int dijkstra() {
      memset(dist, 0x3f, sizeof dist);
      priority_queue<PII, vector<PII>, greater<PII>> heap;
      heap.push({0, 1});
      dist[1] = 0;
    
      while (heap.size()) {
        auto t = heap.top(); heap.pop();
        int ver = t.second, distance = t.first;
        if (st[ver]) continue;
        st[ver] = 1;
    
        for (int i = h[ver]; i; i = ne[i]) {
          int j = e[i];
          if (dist[j] > distance + 1) {
            dist[j] = distance + 1;
            if (!st[j]) heap.push({dist[j], j});
          }
        }
      }
    
      if (dist[m] == 0x3f3f3f3f) return -1;
      return dist[m];
    }
    
    int main() {
      scanf("%d%d", &n, &m); getchar();
      for (int i = 0; i < n; i++) {
        fgets(s, N, stdin);
        build();
      }
    
      int t = dijkstra();
      if (t != -1) printf("%d", t - 1);
      else puts("NO");
    
      return 0;
    }
    

    903. 昂贵的聘礼 - AcWing题库

    本题求以物易物的方式求换取物品1需要的最少花费,那么我们可以将直接购买的物品和优惠物品之间反向建边,这样问题就变成了终点为1,起点为所有物品,边权为价格的最短路问题.

    本题有等级差的限制,但数据范围不是很大,可以枚举等级差的范围,取最小值

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    
    constexpr int N = 110, M = 100010, INF = 0x3f3f3f3f;
    
    typedef pair<int, int> PII;
    int h[N], e[M], ne[M], w[M], idx;
    int n, m, g[N][N], level[N], dist[N];
    bool st[N];
    
    inline void add(int a, int b, int c) {
      e[++idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx;
    }
    
    inline int dijkstra(int lower, int upper) {
      priority_queue<PII, vector<PII>, greater<PII>> heap;
      for (int i = 0; i <= n; i++) { st[i] = 0, dist[i] = INF; }
      heap.push({0, 0});
      dist[0] = 0;
    
      while (heap.size()) {
        auto t = heap.top(); heap.pop();
        int ver = t.second, d = t.first;
    
        if (st[ver]) continue;
        st[ver] = 1;
        
        for (int i = h[ver]; i; i = ne[i]) {
          int j = e[i];
          if (level[j] < lower or level[j] > upper) continue;
          if (dist[j] > d + w[i]) {
            dist[j] = d + w[i];
            if (!st[j]) heap.push({dist[j], j});
          }
        }
      }
    
      return dist[1];
    }
    
    int main() {
      scanf("%d%d", &m, &n);
      for (int i = 1; i <= n; i++) {
        static int p, t;
        scanf("%d%d%d", &p, level + i, &t);
        add(0, i, p);
        while (t --) {
          int a, b; scanf("%d%d", &a, &b);
          add(a, i, b);
        }
      }
    
      int res = INF;
      for (int i = level[1] - m; i <= level[1]; i++) {
        res = min(res, dijkstra(i, i + m));
      }
    
      printf("%d\n", res);
    
      return 0;
    }
    
  • 相关阅读:
    客户端回传事件接口IPostBackEventHandler
    《敏捷无敌》—— 一本非常好看的“IT技术言情小说”
    面向对象之设计
    Zac谈网络编辑需要注意的SEO技巧
    面向对象之领悟
    《网络营销实战密码》推荐
    设计模式建造者模式(builder)
    设计模式工厂方法(FactoryMethod)
    struts1.x与struts2的比较表
    设计模式原型模式(ProtoType)
  • 原文地址:https://www.cnblogs.com/FrankOu/p/15913145.html
Copyright © 2020-2023  润新知