洛谷题单指南-最短路-P1993 小 K 的农场

原题链接:https://www.luogu.com.cn/problem/P1993

题意解读:n个未知数满足一组不等式关系,求是否有一组可能的解。

解题思路:典型的差分约束问题,只需要判断是否有解,因此可以把不等式统一成Xi <=Xj + c的形式,再建立j->i的边,然后用spfa判负环即可。

对于题目中的三种描述:

1、农场  比农场  至少多种植了  个单位的作物;

不等式关系为Xa - Xb >= c,转化为Xb <= Xa - c,建立a->b权值为-c的边

2、农场  比农场  至多多种植了  个单位的作物;

不等式关系为Xa - Xb <= c,转化为Xa <= Xb + c,建立b->a权值为c的边

3、农场  与农场  种植的作物数一样多。

不等式关系为Xa = Xb,转化为Xa <= Xb,Xb <= Xa,建立b->a权值为0的边以及a->b权值为0的边

最后,还要定义一个虚拟起点0,建立从0到所有点的一条权值为0的边。

从0跑一遍SPFA,判断是否有负环即可。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 5005, M = 20005;
int h[N], e[M], w[M], ne[M], idx;
int dist[N], cnt[N];
bool vis[N];
int n, m;

void add(int a, int b, int c)
{
    e[++idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx;
}

bool spfa()
{
    memset(dist, 0x3f, sizeof(dist));
    dist[0] = 0;
    queue<int> q;
    q.push(0);

    while(q.size())
    {
        int u = q.front(); q.pop();
        vis[u] = false;
        for(int i = h[u]; ~i; i = ne[i])
        {
            int v = e[i];
            if(dist[v] > dist[u] + w[i])
            {
                dist[v] = dist[u] + w[i];
                cnt[v] = cnt[u] + 1;
                if(cnt[v] >= n + 1) return true; //有负环
                if(!vis[v])
                {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
    return false;
}

int main()
{
    memset(h, -1, sizeof(h));
    cin >> n >> m;
    while(m--)
    {
        int op, a, b, c;
        cin >> op;
        if(op == 1)
        {
            cin >> a >> b >> c;
            add(a, b, -c);
        }
        else if(op == 2)
        {
            cin >> a >> b >> c;
            add(b, a, c);
        }
        else 
        {
            cin >> a >> b;
            add(a, b, 0), add(b, a, 0);
        }
    }
    for(int i = 1; i <= n; i++) add(0, i, 0);

    if(spfa()) cout << "No";
    else cout << "Yes";

    return 0;
}

 

posted @ 2025-04-11 10:43  hackerchef  阅读(39)  评论(0)    收藏  举报