《P5960 【模板】差分约束》
题目描述
给出一组包含 m 个不等式,有 n 个未知数的形如:
⎩⎨⎧xc1−xc1′≤y1xc2−xc2′≤y2⋯xcm−xcm′≤ym
的不等式组,求任意一组满足这个不等式组的解。
输入格式
第一行为两个正整数 n,m,代表未知数的数量和不等式的数量。
接下来 m 行,每行包含三个整数 c,c′,y,代表一个不等式 xc−xc′≤y。
输出格式
一行,n 个数,表示 x1,x2⋯xn 的一组可行解,如果有多组解,请输出任意一组,无解请输出 NO
。
输入输出样例
输入 #1复制
3 3 1 2 3 2 3 -2 1 3 1
输出 #1复制
5 3 5
说明/提示
样例解释
⎩⎨⎧x1−x2≤3x2−x3≤−2x1−x3≤1
一种可行的方法是 x1=5,x2=3,x3=5。
⎩⎨⎧5−3=2≤33−5=−2≤−25−5=0≤1
数据范围
对于 100% 的数据,1≤n,m≤5×103,−104≤y≤104,1≤c,c′≤n,c=c′。
评分策略
你的答案符合该不等式组即可得分,请确保你的答案中的数据在 int
范围内。
如果并没有答案,而你的程序给出了答案,SPJ 会给出 There is no answer, but you gave it
,结果为 WA;
如果并没有答案,而你的程序输出了 NO
,SPJ 会给出 No answer
,结果为 AC;
如果存在答案,而你的答案错误,SPJ 会给出 Wrong answer
,结果为 WA;
如果存在答案,且你的答案正确,SPJ 会给出 The answer is correct
,结果为 AC。
代码实现:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
int numVars, numConstraints, edgeIdx, head[5005], dist[5005], cnt[5005];
bool inQueue[5005];
struct Edge {
int to, val, next;
} edges[10005];
queue<int> q;
void addEdge(int u, int v, int w) {
edges[++edgeIdx].to = v;
edges[edgeIdx].val = w;
edges[edgeIdx].next = head[u];
head[u] = edgeIdx;
}
bool spfa(int start) {
dist[start] = 0;
q.push(start);
inQueue[start] = true;
cnt[start]++;
while (!q.empty()) {
int u = q.front();
q.pop();
inQueue[u] = false;
for (int i = head[u]; i != 0; i = edges[i].next)
if (dist[edges[i].to] > dist[u] + edges[i].val) {
dist[edges[i].to] = dist[u] + edges[i].val;
if (!inQueue[edges[i].to]) {
q.push(edges[i].to);
inQueue[edges[i].to] = true;
cnt[edges[i].to]++;
if (cnt[edges[i].to] == numVars + 1) return false;
}
}
}
return true;
}
int main() {
scanf("%d %d", &numVars, &numConstraints);
for (int i = 1; i <= numVars; i++)
dist[i] = INT_MAX;
for (int i = 1; i <= numConstraints; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
addEdge(v, u, w);
}
for (int i = 1; i <= numVars; i++)
addEdge(numVars + 1, i, 0);
if (!spfa(numVars + 1)) {
printf("NO");
return 0;
}
for (int i = 1; i <= numVars; i++)
printf("%d ", dist[i]);
return 0;
}