bzoj2330: [SCOI2011]糖果(差分约束)
2330: [SCOI2011]糖果
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9125 Solved: 3167
[Submit][Status][Discuss]
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 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
Sample Output
11
HINT
【数据范围】
对于30%的数据,保证 N<=100
对于100%的数据,保证 N<=100000
对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N
Source
/* 差分约束,根据约束条件建图跑最长路 开long long */ #include<bits/stdc++.h> #define ll long long #define N 300007 using namespace std; int n,k,cnt; int head[N],net[N],to[N],w[N],dis[N],tot[N]; bool vis[N]; queue<int>q; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void add(int u,int v,int c) { to[++cnt]=v,net[cnt]=head[u],head[u]=cnt,w[cnt]=c; } int main() { n=read(),k=read(); int u,v,f; while(k--) { f=read(),u=read(),v=read(); if(f==1)add(u,v,0),add(v,u,0); else if(f==2) { if(u==v){cout<<-1;return 0;} add(u,v,1); } else if(f==3)add(v,u,0); else if(f==4) { if(v==u){cout<<-1;return 0;} add(v,u,1); } else if(f==5)add(u,v,0); } for(int i=n;i>=1;i--) add(0,i,1); vis[0]=1,q.push(0); while(!q.empty()) { int u=q.front();q.pop();vis[u]=0; if(tot[u]==n-1){cout<<-1;return 0;} tot[u]++; for(int i=head[u];i;i=net[i]) if(dis[to[i]]<dis[u]+w[i]) { dis[to[i]]=dis[u]+w[i]; if(!vis[to[i]])vis[to[i]]=1,q.push(to[i]); } } ll ans=0; for(int i=1;i<=n;i++) ans+=dis[i]; cout<<ans; return 0; }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。