洛谷-P1250 种树

Abstract

传送门

Idea

显然是一个差分约束系统。不妨用 dist[i] 表示前 i 个位置种的树的数目,那么,容易得出下列方程:

  1. dist[i] >= dist[i-1]
  2. dist[i] - dist[i-1] <= 1 (每个位置至多能种一颗树)

题目要求 b 到 e 之间至少种 t 棵树,其数学形式就是:

  1. dist[b] - dist[e-1] >= t

依据上面三种方程,我们构建了一个完整的差分约束系统,接下来跑最短路求出 dist 数组的一个可能取值就行了。然后,考虑到边界条件 dist[0] = 0,所以答案是 dist[n] - dist[0] 。

Code

#include <bits/stdc++.h>
using namespace std;
int n, h;
namespace graph
{
    const int maxn = 100000;
    int head[maxn];
    int cnt;
    struct Edge
    {
        int next, to, value;
    } edge[maxn];
    void add(int u, int v, int c)
    {
        edge[++cnt].next = head[u];
        edge[cnt].to = v;
        edge[cnt].value = c;
        head[u] = cnt;
        return;
    }
};

bool SPFA(int start, int dist[])
{
    queue<int> q;
    bool inQueue[graph::maxn] = {false};
    int count[graph::maxn] = {0};
    for (int i = 1; i < n + 1; i++)
    {
        dist[i] = 0x3f3f3f3f;
    }
    dist[start] = 0;
    q.push(start);
    inQueue[start] = true;
    count[start] = 1;

    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        inQueue[u] = false;

        for (int i = graph::head[u]; i; i = graph::edge[i].next)
        {
            int v = graph::edge[i].to;
            int w = graph::edge[i].value;
            if (dist[u] + w < dist[v])
            {
                dist[v] = dist[u] + w;
                if (!inQueue[v])
                {
                    q.push(v);
                    inQueue[v] = true;
                    count[v]++;
                }
                if (count[v] > n + 1)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

void solve()
{
    cin >> n >> h;
    for (int i = 0; i < h; i++)
    {

        int e, b, t;
        cin >> b >> e >> t;
        graph::add(e, b - 1, -t);
    }

    for (int i = 0; i < n; i++)
    {
        graph::add(i, i + 1, 1);
        graph::add(i + 1, i, 0);
    }
    for (int i = 0; i < n + 1; i++)
    {
        graph::add(n + 1, i, 0);
    }

    int dist[graph::maxn];
    SPFA(n + 1, dist);
    cout << dist[n] - dist[0];
    return;
}

signed main()
{
    int t = 1;
    while (t--)
    {
        solve();
    }
    return 0;
}
posted @   carboxylBase  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示