Differential constraint algorithm ---- Luo Gu P4878 [USACO05DEC] Layout

topic:

 

 The main problem is not difficult to see meaning given format ml + md th inequality xi-xj <= ak's, xi-xj distance i, j two cows, should we seek the maximum value x1-xn.

 

 

 

After the vertical acceleration and we these into several inequalities x1-xn <= a1 + a2 + a3 + a4 + .... + ak, in which the subtraction process dijstra figure we can see, this simple calculations the process does not exactly cut loose operate it!

Then we get positive solution - Difference constrained algorithm, which is mainly used for processing the differential restraint system: If the system consists of a variable n and m constraints, which formed inequality m ai-aj≤k of the form ( i, j∈ [1, n] , k is a constant), which is called a differential restraint system.

Conclusion: Solving differential restraint system, may be converted into a graph theory single-source shortest path (or longest path) problem.

 

Relationship between the differential constraints and shortest model

 

We observed that the inequality in the above example, is x [i] - x [j] <= a [k], can be transposed to become x [i] <= x [j] + a [k], we let a [k] = w (j, i), dis [i] = x [i], and i = v, j = u, then the original becomes: dis [u] + w (u, v)> = dis [v], so the code can be associated with a portion of the shortest model

if(dis[u]+w(u,v)<=dis[v])
{
    dis[v]=dis[u]+w(u,v);
}

This is not correct and relaxation operation similar to it?

But it seems the opposite direction of inequality, but in fact this is not contradictory

To achieve the above code is to dis [u] + w (u, v)> dis [v], and for inequality, we built operating side: for each of the inequality x [i] - x [j] < = a [k], the establishment of a node j and j i -> i directed edge, the right edge of a [k], find x [n-1] - x [0] is the maximum value of 0 to seek n-1 is the shortest, both just fit. So to solve the problem is converted to a differential constraint shortest path problem.

Existence of Solutions

Due to the presence of a negative ring or simply not up to the end point will appear in solving the shortest path in solving differential constraint problem also exists

 

(1) a negative ring

If the negative path loop occurs, it represents the shortest path can be infinitely small, i.e. the shortest path does not exist, then the performance of the inequality, i.e. X [n-1] - X [0] <= T T is infinitesimal, stars the conclusion is X [n-1] - the maximum value of X [0] does not exist. A point reflected in the number of the team is greater than the number of nodes in the SPFA implementation process. (Seemingly can sqrt (num_node) instead of reducing the running time)

(2) do not end up

This situation indicates that X [n-1] and without constraints between X [0], X [n- 1] - X [0] is the maximum value of infinity, i.e., X [n-1] and X [0] there are an infinite number of values. Embodied as dis [n-1] = INF code implementation process.

Reference link to the article: https://blog.csdn.net/my_sunshine26/article/details/72849441


note

1. Because of the problems that may exist in a negative right ring (well known dijstra when confronted with this stuff is absolutely no way) so we need to use SPFA

Md inequality title 2. After a start to the are: xj-xi> = a we can deduce xi-xj <= - a (which will be used in the construction diagram after processing) pay attention to the negative right side .

3. The title given condition is not necessarily right, so we need to run twice SPFA judgment map is not Unicom (array circle of usefulness).

Code:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int N=1005;
const int M=40005;
int n,ml,md;
struct EDGE{
    int next,to,w;
}edge[M];
head int [N] everything;
void add(int x,int y,int v){
    edge[++tot].next=head[x];
    edge[tot].to=y;
    edge[tot].w=v;
    head[x]=tot;
}
queue<int> q;
int vis [N], dis [N], circle [N]; // circle to point number tt 
void spfa(int s){
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(circle,0,sizeof(circle));
    q.push(s);
    want [s] = 1, push [i] = 0;
    while(!q.empty()){
        int now=q.front(); 
		q.pop(); 
		vis[now]=0;
        for(int i=head[now];i;i=edge[i].next){
            int tt=edge[i].to;
            if(dis[now]+edge[i].w<dis[tt]){
                dis[tt]=dis[now]+edge[i].w;
                circle [tt] = circle [now] +1; // just above the normal SPFA, but conditions are not necessarily subject to the right 
                if (circle [tt]> = n) {// directed edges than n tt is the natural condition is not satisfied 
                    puts("-1");exit(0);
                }
                if(!vis[tt]){
                    view [TT] = 1;
                    q.push(tt);
                }
            }
        }
    }

}
int main () {
    scanf("%d%d%d",&n,&ml,&md);
    for(int i=1;i<=ml;i++){
    	int a,b,d; 
        scanf("%d%d%d",&a,&b,&d);
        add(a,b,d);//a-b<=d
    }
    for(int i=1;i<=md;i++){
    	int a,b,d;
        scanf("%d%d%d",&a,&b,&d);
        add (b, a, -d); // ba> = d ==> ab <= - d is negative and therefore the right side
    }
    spfa(0);
    spfa(1);
    if(dis[n]==INF) puts("-2");
    else printf("%d",dis[n]);
    return 0;
}

Reference Code: https://www.luogu.org/blog/roy1994/solution-p4878

Guess you like

Origin www.cnblogs.com/myhnb/p/11761542.html