幼儿园里有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。
输入样例#1:
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
输出样例#1:
11
【数据范围】
对于30%的数据,保证 N<=100
对于100%的数据,保证 N<=100000
对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N
话说出题人真是用(sang)心(xin)良(bing)苦(kuang)
差分约束卡SPFA。。
我还能说什么。。
=.=、、、、、、
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<queue>
6 #include<algorithm>
7 #include<cstdlib>
8 #define lli int
9 using namespace std;
10 const int MAXN=233333;
11 inline void read(int &n)
12 {
13 char c='+';int x=0,flag=1;
14 while(c<'0'||c>'9')
15 {c=getchar();if(c=='-')flag=-1;}
16 while(c>='0'&&c<='9')
17 {x=x*10+c-48;c=getchar();}
18 n=(x*flag);
19 }
20 int n,m;
21 struct node
22 {
23 int u,v,w,nxt;
24 }edge[MAXN];
25 int head[MAXN];
26 int num=1;
27 inline void no_ans()
28 {
29 printf("-1");
30 exit(0);
31 }
32 inline void add_edge(int x,int y,int z)
33 {
34 edge[num].u=x;
35 edge[num].v=y;
36 edge[num].w=z;
37 edge[num].nxt=head[x];
38 head[x]=num++;
39 }
40 int dis[MAXN];
41 int vis[MAXN];
42 int happen[MAXN];
43 inline bool SPFA(int p)
44 {
45 if(happen[p]>n)
46 no_ans();
47 vis[p]=1;
48 for(register int i=head[p];i!=-1;i=edge[i].nxt)
49 {
50 if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
51 {
52 dis[edge[i].v]=dis[edge[i].u]+edge[i].w;
53 happen[edge[i].v]++;
54 if(vis[edge[i].v]||!SPFA(edge[i].v))
55 return false;
56 }
57 }
58 vis[p]=0;
59 return true;
60 }
61 int main()
62 {
63 memset(dis,0x3f,sizeof(dis));
64 memset(head,-1,sizeof(head));
65 read(n);read(m);
66 for(register int i=n;i>=1;--i)
67 add_edge(0,i,-1);
68 for(register int i=1;i<=m;++i)
69 {
70 int how,a,b;
71 read(how);read(a);read(b);
72 if(how==1)
73 {
74 add_edge(b,a,0);add_edge(a,b,0);
75 }
76 else if(how==2)
77 {
78 if(a==b)no_ans();
79 add_edge(a,b,-1);
80 }
81 else if(how==3)
82 add_edge(b,a,0);
83 else if(how==4)
84 add_edge(b,a,-1);
85 else if(how==5)
86 add_edge(a,b,0);
87 }
88 dis[0]=0;
89 long long int ans=0;
90 if(SPFA(0))
91 {
92 for(register int i=1;i<=n;++i)
93 ans-=dis[i];
94 }
95 else no_ans();
96 printf("%lld",ans);
97 return 0;
98 }