洛谷题单指南-最短路-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;
}
浙公网安备 33010602011771号