AcWing1169. 糖果
题目描述
幼儿园里有
但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候, 老师需要满足小朋友们的
幼儿园的糖果总是有限的,老师想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
输入格式
输入的第一行是两个整数
接下来
- 如果
.表示第 个小朋友分到的糖果必须和第 个小朋友分到的糖果一样多。 - 如果
,表示第 个小朋友分到的糖果必须少于第 个小朋友分到的糖果。 - 如果
,表示第 个小朋友分到的糖果必须不少于第 个小朋友分到的糖果。 - 如果
,表示第 个小朋友分到的糖果必须多于第 个小朋友分到的糖果。 - 如果
,表示第 个小朋友分到的糖果必须不多于第 个小朋友分到的糖果。
小朋友编号从
输出格式
输出一行,表示老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出
数据范围
输入数据完全随机。
解题思路
超级源点
,使得它一定可以到达图中的所有边
正环
,代表无解,输出
正环
,统计最长路之和,输出。
为什么可以这样求?
因为在一张图中,我们要求
我们每一条从源点到
此时放到我们的差分约束系统建立条件中,等价于我们建立了一条
当我们的不等式有多个解
的时候,我们的
代码
#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
using LL = long long;
const int N = 1e5 + 10, M = 3 * N + 10;
int h[N], e[M], w[M], ne[M], idx;
LL dist[N];
int st[N], n, m, ring, cnt[N];
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}
LL spfa()
{
memset(dist, 0xcf, sizeof dist);
memset(st, 0, sizeof st);
memset(cnt, 0, sizeof cnt);
stack <int> q;
q.push(0), dist[0] = 0, st[0] = 1;
while (!q.empty())
{
auto t = q.top(); q.pop();
st[t] = 0;
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if (dist[j] < dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
cnt[j] = cnt[t] + 1;
if (cnt[j] >= n + 1) return ring = 1;
if (!st[j]) st[j] = 1, q.push(j);
}
}
}
LL res = 0;
for (int i = 1; i <= n; i ++ ) res += dist[i];
return res;
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
while (m -- )
{
int op, u, v;
scanf("%d%d%d", &op, &u, &v);
if (op == 1) add(v, u, 0), add(u, v, 0);
if (op == 2) add(u, v, 1);
if (op == 3) add(v, u, 0);
if (op == 4) add(v, u, 1);
if (op == 5) add(u, v, 0);
}
for (int i = 1; i <= n; i ++ ) add(0, i, 1);
ring = 0;
LL t = spfa();
if (ring) puts("-1");
else printf("%lld\n", t);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)