[algorithm problem inductive collection] graph theory - difference constraint

Posted by Ell20 on Fri, 11 Feb 2022 05:47:05 +0100

The application explanation of differential constraint can jump to: Principle and application of differential constraint algorithm

1, AcWing 1169 candy

[Title Description]
In kindergarten N N N children. Now the teacher wants to distribute candy to these children and requires each child to get candy.
But the children are also jealous and will always put forward some requirements. For example, Xiao Ming doesn't want Xiao Hong to get more candy than him, so the teacher needs to meet the children's needs when distributing candy K K K requirements.
The candy in kindergarten is always limited. The teacher wants to know how many candy he needs to prepare at least, so that every child can get candy and meet all the requirements of the children.

[input format]
The first line of input is two integers N , K N,K N,K.
next K K Line K represents the relationship to be satisfied when distributing candy. Each line 3 3 3 numbers X , A , B X,A,B X,A,B.

  • If X = 1 X=1 X=1. Indicates the second A A The candy given by A child must be the same as that given by the third child B B B children are given the same amount of candy.
  • If X = 2 X=2 X=2, indicating the second A A A child must receive less candy than the third child B B B is the candy given to the children.
  • If X = 3 X=3 X=3, indicating the second A A A child must be given no less than the third candy B B B is the candy given to the children.
  • If X = 4 X=4 X=4, indicating the second A A A child must receive more candy than the third B B B is the candy given to the children.
  • If X = 5 X=5 X=5, indicating the second A A A child must receive no more candy than the third child B B B is the candy given to the children.

Children number from 1 1 1 to N N N.

[output format]
The output line indicates the number of sweets that the teacher needs to prepare at least. If it can't meet all the requirements of the children, it will be output − 1 -1 −1.

[data range]
1 ≤ N < 1 0 5 1≤N<10^5 1≤N<105
1 ≤ K ≤ 1 0 5 1≤K≤10^5 1≤K≤105
1 ≤ X ≤ 5 1≤X≤5 1≤X≤5
1 ≤ A , B ≤ N 1≤A,B≤N 1≤A,B≤N

[input example]

5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1

[output example]

11

[analysis]

This problem needs to find the minimum total number of candy, so we can find the minimum value of each variable in the inequality group by finding the longest path.
First, the inequalities of five relationships are expressed:

  • A = B → A ≥ B , B ≥ A A=B→A\ge B,B\ge A A=B→A≥B,B≥A
  • A < B → B ≥ A + 1 A<B→B\ge A+1 A<B→B≥A+1
  • A ≥ B A\ge B A≥B
  • A > B → A ≥ B + 1 A>B→A\ge B+1 A>B→A≥B+1
  • A ≤ B → B ≥ A A\le B→B\ge A A≤B→B≥A

Because each child needs at least one sugar, the additional conditions are X i ≥ 1 X_i\ge 1 Xi​≥1.
Set super source point X 0 = 0 X_0=0 X0 = 0, then the above formula can be written as X i ≥ X 0 + 1 X_i\ge X_0+1 Xi ≥ X0 + 1, i.e. one line from super source point to all points, with a length of 1 1 1.

In addition, if the problem uses the queue, it will timeout, so you need to use the stack.

[Code]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;

typedef long long LL;
const int N = 100010, M = 300010;
int e[M], ne[M], d[M], h[N], idx;
int dis[N], cnt[N];
bool st[N];
int n, m;

void add(int u, int v, int w)
{
    e[idx] = v, d[idx] = w, ne[idx] = h[u], h[u] = idx++;
}

//The return value indicates whether there is a positive ring
bool spfa()
{
    memset(dis, 0x8f, sizeof dis);//Find the longest path, so initialize to negative infinity
    dis[0] = 0;
    stack<int> Q;//Sometimes it's faster to use stacks instead of queues when looking for rings
    Q.push(0);
    st[0] = true;
    while (Q.size())
    {
        int t = Q.top();
        Q.pop();
        st[t] = false;
        for (int i = h[t]; ~i; i = ne[i])
            if (dis[t] + d[i] > dis[e[i]])
            {
                dis[e[i]] = dis[t] + d[i];
                cnt[e[i]] = cnt[t] + 1;
                if (cnt[e[i]] >= n + 1) return true;
                if (!st[e[i]]) Q.push(e[i]), st[e[i]] = true;
            }
    }
    return false;
}

int main()
{
    cin >> n >> m;
    memset(h, -1, sizeof h);
    while (m--)
    {
        int x, a, b;
        cin >> x >> a >> b;
        if (x == 1) add(a, b, 0), add(b, a, 0);
        else if (x == 2) add(a, b, 1);
        else if (x == 3) add(b, a, 0);
        else if (x == 4) add(b, a, 1);
        else add(a, b, 0);
    }
    for (int i = 1; i <= n; i++) add(0, i, 1);
    if (spfa()) cout << -1 << endl;
    else
    {
        LL res = 0;
        for (int i = 1; i <= n; i++) res += dis[i];
        cout << res << endl;
    }
    return 0;
}
/*
X = 1: A >= B && B >= A
X = 2: B >= A + 1
X = 3: A >= B
X = 4: A >= B + 1
X = 5: B >= A
 Additional conditions: dis [1 ~ n] > = 1. If the virtual source point dis[0] = 0, then dis [1 ~ n] > = dis [0] + 1
*/

Topics: C++ Algorithm data structure Graph Theory