[luogu P3275] [SCOI2011]糖果
题目描述
幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
输入输出格式
输入格式:
输入的第一行是两个整数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个小朋友分到的糖果;
输出格式:
输出一行,表示lxhgww老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出-1。
输入输出样例
5 7 1 1 2 2 3 2 4 4 1 3 4 5 5 4 5 2 3 5 4 5 1
11
说明
【数据范围】
对于30%的数据,保证 N<=100
对于100%的数据,保证 N<=100000
对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N
也是一道容易看出来的差分题。
但是这题点数和边数都在1e5的级别,还要判正环,spfa极其容易被卡掉。。但是本蒟蒻只会spfa判正环,怎么办??
交了好几发,TLE80,TLE90,怎么卡都卡不过去。。
后来%了某些dalao的code,加了两个特判,然后加了一个奇奇怪怪的剪枝(直接把所有点push,而不是建超级源),然后就A掉了。
更奇怪的是,我发现两个特判加上只能90分,有了后面的剪枝就100了,而且原来T的点跑得飞快。。。
真是令人百思不得其解(竟然快了这么多。。)
说到卡时间,还要%一下zzydalao。。
code:
%:pragma GCC optimize() #include<bits/stdc++.h> #define LL long long #define RI register int #define Ms(a,x) memset(a,x,sizeof a) using namespace std; ,M=; int n,m,inf,tot; bool vis[N]; int lnk[N],nxt[M],son[M],w[M],f[N],dis[N]; queue <int> Q; inline int read() { ,f=; char ch=getchar(); :,ch=getchar(); +ch-',ch=getchar(); return x*f; } void add(int x,int y,int z) { nxt[++tot]=lnk[x],lnk[x]=tot,son[tot]=y,w[tot]=z; } bool spfa() { for (RI x; !Q.empty(); ) { x=Q.front(),Q.pop(),vis[x]=; for (RI j=lnk[x],y; j; j=nxt[j]) if (dis[y=son[j]]<dis[x]+w[j]) { dis[y]=dis[x]+w[j]; ; ,Q.push(y); } } ; } int main() { n=read(),m=read(); ; i<=n; i++) dis[i]=f[i]=vis[i]=,Q.push(i); ,x,y,z; i<=m; i++) { z=read(),x=read(),y=read(); switch (z) { :add(x,y,),add(y,x,); break; :;} add(x,y,); break; :add(y,x,); break; :;} add(y,x,); break; :add(x,y,); break; } } LL ans=; ; else ; i<=n; i++) ans+=dis[i]; cout<<ans<<'\n'; ; }