https://www.luogu.org/problemnew/show/P1993
小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述:
农场a比农场b至少多种植了c个单位的作物,
农场a比农场b至多多种植了c个单位的作物,
农场a与农场b种植的作物数一样多。
但是,由于小K的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
标准差分约束,优化spfa为dfs形式判断环和负环情况,求a - b >= c得最小值即求最长路
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
const int maxn = 1e4 + 10;
const int INF = 0x3f3f3f3f;
struct node {
int v, w;
node() {}
node(int _v, int _w) : v(_v), w(_w) {}
};
vector<node> E[maxn];
int dis[maxn], vis[maxn];
int n, m, t, a, b, c;
void init() {
for (register int i = 1; i <= n; i++) dis[i] = -INF;
}
bool spfa(int u) {
vis[u] = 1;
for(node nv : E[u]) {
if(dis[nv.v] < dis[u] + nv.w) {
dis[nv.v] = dis[u] + nv.w;
if(vis[nv.v]) return false;
if(!spfa(nv.v)) return false;
}
}
vis[u] = 0;
return true;
}
int main()
{
scanf("%d%d", &n, &m);
for(register int i = 0; i < m; i++) {
scanf("%d", &t);
//a - b >= c
if(t == 1) {
scanf("%d%d%d", &a, &b, &c);
E[a].emplace_back(node(b, c));
}
//a - b <= c -> b - a <= -c
else if(t == 2) {
scanf("%d%d%d", &a, &b, &c);
E[b].emplace_back(node(a, -c));
}
else {
scanf("%d%d", &a, &b);
E[b].emplace_back(node(a, 0));
E[a].emplace_back(node(b, 0));
}
}
for (register int i = 1; i <= n; i++)
E[0].emplace_back(node(i, 0));
init();
printf("%s\n", spfa(0) ? "Yes" : "No");
// system("pause");
}