[spfa][差分约束] Bzoj 2330 糖果

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

Sample Output

11

Hint

对于30%的数据,保证 N<=100
对于100%的数据,保证 N<=100000
对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N

 

题解

  • 这很显然就是差分约束系统,然后跑最长路就好了

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <queue> 
 5 #define ll long long
 6 using namespace std;
 7 const int N=300010;
 8 int n,k,cnt,head[N],dis[N],tot[N];
 9 ll ans;
10 bool vis[N];
11 queue<int>Q;
12 struct edge {int to,from,v;}e[N];
13 void insert(int x,int y,int v) { e[++cnt].to=y,e[cnt].from=head[x],e[cnt].v=v,head[x]=cnt; }
14 int read()
15 {
16     char ch=getchar(); int x=0;
17     while (ch<'0'||ch>'9') ch=getchar();
18     while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar(); 
19     return x;
20 }
21 int main()
22 {
23     n=read(),k=read();    
24     for (int i=1,x,a,b;i<=k;i++)
25     {
26         x=read(),a=read(),b=read();
27         if (x==1) insert(a,b,0),insert(b,a,0);
28         if (x==2) 
29         {
30             if (a==b) { printf("-1"); return 0; }
31             insert(a,b,1);
32         }
33         if (x==3) insert(b,a,0);
34         if (x==4)
35         {
36             if (a==b) { printf("-1"); return 0; }
37             insert(b,a,1);
38         }
39         if (x==5) insert(a,b,0);
40     }
41     for (int i=n;i>=1;i--) insert(0,i,1);
42     vis[0]=1,Q.push(0);
43     while (!Q.empty())
44     {
45         int u=Q.front(); Q.pop(),vis[u]=0;
46         if (tot[u]==n-1) { printf("-1"); return 0; }
47         tot[u]++;
48         for (int i=head[u];i;i=e[i].from)
49             if (dis[e[i].to]<dis[u]+e[i].v)
50             {
51                 dis[e[i].to]=dis[u]+e[i].v;
52                 if (!vis[e[i].to]) Q.push(e[i].to),vis[e[i].to]=1;
53             }
54     }
55     for (int i=1;i<=n;i++) ans+=dis[i];
56     printf("%lld",ans);
57 }

 

posted @ 2019-07-05 16:36  BEYang_Z  阅读(156)  评论(0编辑  收藏  举报