1169. 糖果

题目链接

1169. 糖果

幼儿园里有 N 个小朋友,老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。

但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候, 老师需要满足小朋友们的 K 个要求。

幼儿园的糖果总是有限的,老师想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。

输入格式

输入的第一行是两个整数 N,K

接下来 K 行,表示分配糖果时需要满足的关系,每行 3 个数字 X,A,B

  • 如果 X=1.表示第 A 个小朋友分到的糖果必须和第 B 个小朋友分到的糖果一样多。

  • 如果 X=2,表示第 A 个小朋友分到的糖果必须少于第 B 个小朋友分到的糖果。

  • 如果 X=3,表示第 A 个小朋友分到的糖果必须不少于第 B 个小朋友分到的糖果。

  • 如果 X=4,表示第 A 个小朋友分到的糖果必须多于第 B 个小朋友分到的糖果。

  • 如果 X=5,表示第 A 个小朋友分到的糖果必须不多于第 B 个小朋友分到的糖果。

小朋友编号从 1N

输出格式

输出一行,表示老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出 1

数据范围

1N<105,
1K105,
1X5,
1A,BN,
输入数据完全随机。

输入样例:

5 7 1 1 2 2 3 2 4 4 1 3 4 5 5 4 5 2 3 5 4 5 1

输出样例:

11

解题思路

差分约束

差分约束用来解决类似多个 xixi+1+ci 这样的不等式的可行解或最优解的问题,而 xixi+1+ci 正好对应求解最终最短路的形式,即求解最短路时,最终会有 xic1+c2+ck 的形式,即在所有的下界中取最小值,此时取得的 xi 为最大值,否则如果出现负环的话,即最终会循环到某个点,会产生矛盾,此时无解,同理,求解最长路对应求解每个 xi 的最小值,当出现正环时无解。另外,由于给出的关系可能都为相对关系,而求解的往往需要绝对关系,可以建立一个虚拟源点 x0,即 d[x0]=0,将该点添加到其他关系中连边

本题求解最小值,故求最长路,且要求所有 xi1,即 xix0+1,将 01 之间连一条边权为 1 的边即可,其他建边同理,最后求一遍 spfa 即可

  • 时间复杂度:O(kn)

代码

// Problem: 糖果 // Contest: AcWing // URL: https://www.acwing.com/problem/content/1171/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=1e5+5; int n,k,x; int d[N],cnt[N]; int h[N],e[N*3],w[N*3],ne[N*3],idx; bool v[N]; void add(int a,int b,int c) { e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++; } bool spfa() { stack<int> stk; stk.push(0); v[0]=true; memset(d,-0x3f,sizeof d); d[0]=0; while(stk.size()) { int x=stk.top(); stk.pop(); v[x]=false; for(int i=h[x];~i;i=ne[i]) { int y=e[i],ww=w[i]; if(d[y]<d[x]+ww) { d[y]=d[x]+ww; cnt[y]=cnt[x]+1; if(cnt[y]>=n+1)return false; if(!v[y])stk.push(y),v[y]=true; } } } return true; } int main() { scanf("%d%d",&n,&k); memset(h,-1,sizeof h); while(k--) { int a,b; scanf("%d%d%d",&x,&a,&b); if(x==1)add(a,b,0),add(b,a,0); else if(x==2)add(a,b,1); else if(x==3)add(b,a,0); else if(x==4)add(b,a,1); else add(a,b,0); } for(int i=1;i<=n;i++)add(0,i,1); if(!spfa())puts("-1"); else { LL res=0; for(int i=1;i<=n;i++)res+=d[i]; printf("%lld",res); } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16580349.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示