#include<bits/stdc++.h> usingnamespace std; #define int long long constint INF = LLONG_MAX; intidx(int node, int state) { return (node - 1) * 2 + state; } signedmain() { int n, m, X; cin >> n >> m >> X; vector<vector<int>> g(n + 1), gr(n + 1); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; g[u].push_back(v); gr[v].push_back(u); } int total = n * 2; vector<int> dist(total, INF); priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int> > > pq; dist[idx(1, 0)] = 0; pq.push(make_pair(0, idx(1, 0))); while (!pq.empty()) { pair<int, int> topPair = pq.top(); pq.pop(); int d = topPair.first; int cur = topPair.second; if (d != dist[cur]) { continue; } int node = cur / 2 + 1; int state = cur % 2; if (node == n) { cout << d; return0; } if (state == 0) { for (int i = 0; i < g[node].size(); i++) { int nxt = g[node][i]; int nxtIdx = idx(nxt, state); if (d + 1 < dist[nxtIdx]) { dist[nxtIdx] = d + 1; pq.push(make_pair(dist[nxtIdx], nxtIdx)); } } } else { for (int i = 0; i < gr[node].size(); i++) { int nxt = gr[node][i]; int nxtIdx = idx(nxt, state); if (d + 1 < dist[nxtIdx]) { dist[nxtIdx] = d + 1; pq.push(make_pair(dist[nxtIdx], nxtIdx)); } } } int flipIdx = idx(node, 1 - state); if (d + X < dist[flipIdx]) { dist[flipIdx] = d + X; pq.push(make_pair(dist[flipIdx], flipIdx)); } } cout << "taomenyongcun!!!"; // 显然不会到达这一行 return0; }
F.Smooth Occlusion
题目描述
ht有 2N 颗牙齿:N 颗上牙和 N 颗下牙。
从左数第 i 颗上牙的长度为 Ui(1≤i≤N),从左数第 i 颗下牙的长度为 Di(1≤i≤N)。
#include<bits/stdc++.h> usingnamespace std; #define int long long int n, diff; boolcheck(int mid, const vector<int>& up, const vector<int>& down){ int l = max(0LL, mid - down[0]); int r = min(up[0], mid); if (l > r) { return0; } for (int i = 1; i < n; i++) { int lb = max(0LL, mid - down[i]); int rb = min(up[i], mid); l = max(lb, l - diff); r = min(rb, r + diff); if (l > r) { return0; } } return1; } signedmain() { cin >> n >> diff; vector<int> up(n), down(n); int sum = 0; int maxH = LLONG_MAX; for (int i = 0; i < n; i++) { cin >> up[i] >> down[i]; sum += up[i] + down[i]; maxH = min(maxH, up[i] + down[i]); } int l = 0, r = maxH, ans = 0; while (l <= r) { int mid = (l + r) / 2; if (check(mid, up, down)) { ans = mid; l = mid + 1; } else { r = mid - 1; } } cout << sum - ans * n; return0; }