BZOJ2330 [SCOI2011] 糖果
2018 年 03 月 14 日发布.
Description
$n$个正整数变量,一些大于/大于等于/等于的条件,求这些变量的和的最小值。无解输出$-1$。$n\leqslant 10^5$,约束个数$\leqslant 10^5$。
Solution
强行差分约束...容易发现求最长路的时候其实就是求出了变量最小的取值。
Code
#include <algorithm>
#include <cstdio>
#include <cstring>
const int N = 100050;
int pre[N], nxt[N * 2], to[N * 2], c[N * 2], cnt;
void addEdge(int a, int b, int v) {
[cnt] = pre[a];
nxt[cnt] = v;
c[pre[a] = cnt++] = b;
to}
bool inque[N];
int dis[N];
int que[N], hd, tl;
int main() {
int n, m;
("%d%d", &n, &m);
scanf(pre, -1, sizeof pre);
memsetint x, a, b;
while (m--) {
("%d%d%d", &x, &a, &b);
scanfif (x == 5) addEdge(a, b, 0);
else if (x == 4) addEdge(b, a, 1);
else if (x == 3) addEdge(b, a, 0);
else if (x == 2) addEdge(a, b, 1);
else { addEdge(a, b, 0); addEdge(b, a, 0); }
}
= tl = 0;
hd for (int i = 1; i <= n; ++i) {
[i] = 1;
dis[que[tl++] = i] = true;
inque}
int maxv = 0;
while (hd != tl && maxv <= n) {
int x = que[hd++];
[x] = false;
inque%= N;
hd for (int i = pre[x]; ~i; i = nxt[i])
if (dis[to[i]] < dis[x] + c[i]) {
= std::max(maxv, dis[to[i]] = dis[x] + c[i]);
maxv if (!inque[to[i]]) {
[que[tl++] = to[i]] = true;
inque%= N;
tl }
}
}
if (maxv > n) { puts("-1"); return 0; }
long long ans = 0;
for (int i = 1; i <= n; ++i) ans += dis[i];
("%lld\n", ans);
printfreturn 0;
}