bzoj 2330: [SCOI2011]糖果
2330: [SCOI2011]糖果
Description
幼兒園里有N個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,于是在分配糖果的時候,lxhgww需要滿足小朋友們的K個要求。幼兒園的糖果總是有限的,lxhgww想知道他至少需要準備多少個糖果,才能使得每個小朋友都能夠分到糖果,并且滿足小朋友們所有的要求。
Input
輸入的第一行是兩個整數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個小朋友分到的糖果;
Output
輸出一行,表示lxhgww老師至少需要準備的糖果數,如果不能滿足小朋友們的所有要求,就輸出-1。?
Sample Input
5 71 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
Sample Output
11HINT
【數據范圍】
??? 對于30%的數據,保證 N<=100
??? 對于100%的數據,保證 N<=100000
對于所有的數據,保證 K<=100000,1<=X<=5,1<=A, B<=N
題解:
很裸的差分約束,就是條件多了一些。。
題目說要求老師至少需要準備的糖果數,即需要每個人的糖果數盡量少,我們按x+z<=y建x到y的邊,長度為z,然后求最長路。
注意判環以及建一個超級源點。
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; int i,n,m,x,y,z,t,p[100005],g[100005],r[100005]; int tot,head[100005],Next[400005],to[400005],v[400005]; long long ans,dis[100005]; void add(int x,int y,int z) {tot++;to[tot]=y;v[tot]=z;Next[tot]=head[x];head[x]=tot; } int main() {scanf("%d%d",&n,&m);for(i=0;i<=n;i++)head[i]=-1;for(i=1;i<=m;i++){scanf("%d%d%d",&z,&x,&y);if(z==1){add(x,y,0);add(y,x,0);} elseif(z==2){if(x==y) {printf("-1");return 0;}add(x,y,1);} elseif(z==3) add(y,x,0);elseif(z==4){if(x==y) {printf("-1");return 0;}add(y,x,1);} elseif(z==5) add(x,y,0);}for(i=1;i<=n;i++)add(0,i,1);dis[0]=0;t=1;g[1]=0;p[0]=1;r[0]=1;while(t){x=g[t];t--;p[x]=0;for(i=head[x];i!=-1;i=Next[i])if(dis[x]+v[i]>dis[to[i]]){dis[to[i]]=dis[x]+v[i];if(p[to[i]]==0){r[to[i]]++;if(r[to[i]]>n) {printf("-1");return 0;}p[to[i]]=1;t++;g[t]=to[i];}}}ans=0;for(i=1;i<=n;i++)ans+=dis[i];cout<<ans;return 0; }?
轉載于:https://www.cnblogs.com/lwq12138/p/5448380.html
總結
以上是生活随笔為你收集整理的bzoj 2330: [SCOI2011]糖果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法分类整理+模板②:字符串处理
- 下一篇: ListGetandSetDemo 集合