差分约束基础题
P1645 序列
BIT + 并查集 + 贪心
#include <bits/stdc++.h>
using namespace std;
struct Fenwick {
int n;
vector<int> bit;
Fenwick(int n) : n(n), bit(n + 1, 0) {}
void update(int idx) {
for(; idx <= n; idx += idx & -idx) bit[idx] += 1;
}
int sum(int idx) {
int res = 0;
for(; idx > 0; idx -= idx & -idx) res += bit[idx];
return res;
}
int query(int l, int r) {
return sum(r) - sum(l - 1);
}
};
void solve() {
int n; cin >> n;
vector<tuple<int, int, int>> val;
int mx = 0;
for(int i = 0; i < n; i ++) {
int l, r, c; cin >> l >> r >> c;
val.push_back({l + 1, r + 1, c});
mx = max(mx, r + 1);
}
sort(val.begin(), val.end(), [](const auto& a, const auto& b) {
auto [al, ar, ac] = a;
auto [bl, br, bc] = b;
if(ar != br) return ar < br;
if(al != bl) return br > ar;
return bc > ac;
});
vector<int> pa(mx + 1);
iota(pa.begin(), pa.end(), 0);
Fenwick bit(mx + 2);
auto findu = [&](int id) {
int k = pa[id];
pa[id] = pa[k - 1];
return k;
};
for(auto & [l, r, c] : val) {
int cur = bit.query(l, r);
if(cur >= c) continue;
int dif = c - cur;
while(dif --) {
int x = findu(r);
bit.update(x);
}
}
cout << bit.query(1, mx) << "\n";
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
solve();
return 0;
}
差分约束方法
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
void solve() {
int n; cin >> n;
vector<tuple<int, int, int>> val;
int M = 0;
for(int i = 0; i < n; i ++) {
int l, r, c; cin >> l >> r >> c;
val.push_back({l + 1, r + 1, c});
M = max(M, r + 1);
}
vector<vector<pair<int, int>>> adj(M + 1);
for(auto [l, r, c] : val) {
adj[l - 1].push_back({r, c});
}
for(int i = 1; i <= M; i ++) {
adj[i - 1].push_back({i, 0}); // S(i) >= S(i-1)
adj[i].push_back({i - 1, -1}); // S(i-1) >= S(i) - 1
}
vector<int> dist(M + 1, -INF);
vector<bool> inq(M + 1, false);
queue<int> q;
dist[0] = 0; q.push(0); inq[0] = true;
while(!q.empty()) {
int u = q.front(); q.pop();
inq[u] = false;
for(auto [v, w] : adj[u]) {
if(dist[v] < dist[u] + w) {
dist[v] = dist[u] + w;
if(!inq[v]) {
q.push(v); inq[v] = true;
}
}
}
}
cout << dist[M] << '\n';
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
solve();
return 0;
}
P1260 工程规划
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<int, int>;
using vvi = vector<vector<int>>;
void solve() {
int n, m; cin >> n >> m;
vector<vector<pll>> g(n + 1);
for(int i = 0; i < m; i ++) {
int u, v, w; cin >> u >> v >> w;
g[v].push_back({u, w});
}
vector<ll> dist(n + 1, 0);
vector<int> cnt(n + 1, 0);
vector<bool> vis(n + 1, true);
queue<int> q;
for(int i = 1; i <= n; i ++) q.push(i);
while(!q.empty()) {
int u = q.front(); q.pop();
vis[u] = false;
for(auto& [v, w] : g[u]) {
if(dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
cnt[v] = cnt[u] + 1;
if(cnt[v] >= n) {
cout << "NO SOLUTION\n";
return;
}
if(!vis[v]) {
q.push(v); vis[v] = true;
}
}
}
}
long long mn = *min_element(dist.begin() + 1, dist.end());
for(int i = 1; i <= n; i ++) cout << dist[i] - mn << '\n';
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int _=1; //cin >> _;
while(_--) solve();
return 0;
}

浙公网安备 33010602011771号