差分约束基础题

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;
}
posted @ 2026-09-08 10:07  thenrify  阅读(7)  评论(0)    收藏  举报