AcWing 第94场周赛
4870. 装物品 – AcWing题库
4870 装物品
4870. 装物品 – AcWing题库
巨简单题
#include using namespace std;int main() { int n; cin >> n; if (n % 5 == 0) cout << (n / 5) << endl; else cout << (n / 5) + 1 << endl; return 0;}
4871⭐⭐最早时刻
4871. 最早时刻 – AcWing题库
考查堆优化版迪杰斯特拉变形
- 越早到达,越早离开 => 每个点维护一个最早到达时刻
- 如果 delay 小于 0,就不能用迪杰斯特拉算法
#include #define x first#define y secondusing namespace std;int const N = 1e5 + 10, M = N << 1;int const INF = 0x3f3f3f3f;int h[N], e[M], ne[M], idx, w[M];int dist[N];bool st[N];int n, m;unordered_set stop[N];void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;}// 返回需要等待的时间int next(int u, int t) { int cnt = 0; while (stop[u].count(t)) t++, cnt++; return cnt;}// 堆优化版迪杰斯特拉typedef pair PII;int dijkstra() { priority_queue<PII, vector, greater> heap; memset(dist, 0x3f, sizeof dist); dist[1] = 0; heap.push({0, 1}); while (heap.size()) { // 取最短路径 auto t = heap.top(); heap.pop(); int u = t.y; // ^ 当前点是否已经走过 if (st[u]) continue; // 记录当前点已经走过 st[u] = true; // 更新其他路径 int nw = next(u, dist[u]); for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] > dist[u] + w[i] + nw) { dist[j] = dist[u] + w[i] + nw; heap.push({dist[j], j}); } } } if (dist[n] == INF) return INF; else return dist[n];}int main() { memset(h, -1, sizeof h); cin >> n >> m; for (int i = 0; i > a >> b >> c; add(a, b, c); add(b, a, c); } for (int i = 1; i > k; while (k--) { int t; cin >> t; stop[i].insert(t); } } // 判断 int ans = dijkstra(); if (ans == INF) ans = -1; cout << ans << endl; return 0;}
4872⭐⭐最短路之和
4872. 最短路之和 – AcWing题库
- 最终结果可能是 \(500^2 * 10^5\) 可能会爆int,需要用 long long 存
- 求任意 u,v 间的最短路径,需要用 Floyed 算法
- 每次删一个点,直到点删完
- 每次删一个点不太好做,可以倒过来,每次加一个点
弗洛伊德算法状态表示\(d(k,i,j\)) 是 所有从 i 出发,最终走到 j,且中间只经过节点编号不超过 k 的所有路径
外层循环按照加点的顺序循环,每次加点之后统计一下任意两点距离之和
#include using namespace std;typedef long long LL;int const N = 5e2 + 10;int n;int d[N][N];int p[N];LL ans[N];bool st[N];int main() { cin >> n; for (int i = 1; i <= n; i++) for (int j = 1; j > d[i][j]; for (int i = 1; i > p[i]; for (int u = n; u; u--) { int k = p[u]; st[k] = true; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (st[i] && st[j]) ans[u] += d[i][j]; } for (int i = 1; i <= n; i++) cout << ans[i] << " "; return 0;}