题目描述:
思路:
这道题可以用差分约束来做。
既然是用差分约束,那么我们就要先找不等关系。题目很贴心,直接为我们一条条列好了五种情况。我们只需要把它们转化为式子即可。由于我们要求最小值,所以要使用最长路径,即将所有关系用">="号连接。
①X = 1时,A == B,所以A >= B且B >= A;
②X = 2时,A < B,所以B >= A + 1;
③X = 3时,A >= B;
④X = 4时,A > B,所以A >= B + 1;
⑤X = 5时,A <= B,所以B >= A。
将以上不等式转化为建边操作,则会得到:
①add(a, b, 0), add(b, a, 0);
②add(a, b, 1);
③add(b, a, 0);
④add(b, a, 1);
⑤add(a, b, 0)。
其中add(a, b, c)表示在a点和b点之间连接一条长度为c的边。
然后我们使用最长路径即可求得每一个变量的最小合法取值,答案输出它们的总和即可。
注意:
根据差分约束的性质,如果要求一个最值,那么一定要有不等式满足形式**“x <=(或>=) c”**,其中c为常数。在本题中,根据题意“每个小朋友都分到糖果”可知,所有x都满足x >= 1。这个式子我们可以表示为xi > x0 + 1,其中x0 = 0。所以,我们可以将0号点看作虚拟原点,在0和所有点之间连接一条长度为1的边,来表示“x >= 1”这个条件。代码表示为:
for(int i = 1 ; i <= n ; i ++ )
add(0, i, 1);
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10, M = 3 * N;
int cnt[N], dist[N], q[N];
int h