Luogu P5590 racing game explanations

Luogu P5590 racing game explanations

EDITORIAL

This is a well-known solution to a problem, of course, this is a summary of experience.

It is derived from the Luo Valley Race month, Portal: P5590 racing game

I write this solution to a problem, one hopes not to repeat their own mistakes this time, the second is hoping to help you.

Part of the solution to a problem

Analysis of problems surface

The meaning of problems can be summarized as substantially: you \ (n-\) points \ (m \) edges of a picture, you need to add to each edge of the right side, so that the \ (1-n \) in all paths They are equal length.

Now feeling much simpler problem, we can expect violence to add the right side (right side anyway only \ (1-9 \) )

Problem-solving ideas

Obviously the above is not to get out of the way. And I get this question and not thought to fight violence.

We assume that this figure there are two vertices \ (U, v \) , right to the edge between them \ (Val (U, v) \) .

Then there is: \ (DIS [U] + Val (U, V) = DIS [V] \) ( \ (DIS \) array nodes \ (1 \) to other points of the path length of the longest value)

As for what the most value, and then answer later.

I made the above formula, then it is obvious that we have requested \ (Val (U, v) \) , which things must satisfy \ (1≤val (u, v) ≤9 \)

Well, now look at the deformation formula: \ (1≤val (U, v) = DIS [v], DIS [U] ≤9 \) , see what it?

You look at: \ (1≤dis [v], DIS [U] ≤9 \) , differential constraints?

Yes, that is the differential constraint, the constraint: \ [\ left \ {\ the aligned} {DIS the begin [V], DIS [U] ≧ 1 \\ DIS [U], DIS [V] ≥. 9-\\ \ End {aligned} \ right. \]

The experience of difference constraints, from the \ (u \) to \ (v \) and even an edge right to \ (1 \) side, from \ (v \) to (u \) \ even one side the right to \ (-9 \) side of the road can run the longest.

If \ (the SPFA \) ran out of the ring is negative, then no solution, or the length of each side is \ (DIS [V], DIS [U] \) (now visible \ (DIS \) being the longest path)

Implementation details

First thing you know we only know \ (1 ~ n \) path, so we pros and cons of each drawing run again, those \ (1 \) can not reach the node and \ (n \) can not reach the node weed out, left node under what we really want to be constrained nodes, those nodes corresponding to the cull side may be lightly assignment friends ......

This operation can be twice \ (DFS \) or \ (BFS \) implementation. But because I just built a map, so I used the edge XOR principle of equal positive and negative numbers.

So I just wrote a \ (dfs \) function

void check(int x, bool *flag, int op) {
    if(flag[x]) return;
    flag[x] = 1;
    for(int i = head[x]; i; i = Next[i]) {
        if(~i & op) continue;
        int y = ver[i];
        check(y, flag, op);
    }
}

But \ (op \) only \ (0 \) and \ (1 \) , and the \ (0 \) ...... collapse collapse

The correct wording:

void check(int x, bool *flag, int op) {
    if(flag[x]) return;
    flag[x] = 1;
    for(int i = head[x]; i; i = Next[i]) {
        if((i & 1) == op) continue;
        int y = ver[i];
        check(y, flag, op);
    }
}

Then pay attention to special sentenced \ (1 \) not to \ (n \) situation, but also output \ (- 1 \) .

Next, look at the code to understand it

\(Code:\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;

/*
约束条件
d[a] + val<a,b> = d[b]
1 <= d[b] - d[a] <= 9
*/

const int N = 1e5 + 10, M = N << 2;
int head[N], Next[M], ver[M];
int edge[M], cnt = 1;
struct rec {
    int x, y;
} e[M >> 1];

void add(int x, int y, int v) {
    ver[++cnt] = y, edge[cnt] = v;
    Next[cnt] = head[x], head[x] = cnt;
}

void Add(int x, int y) {
    add(x, y, 0), add(y, x, 0);
}

bool v1[N], v2[N];
void check(int x, bool *flag, int op) {
    if(flag[x]) return;
    flag[x] = 1;
    for(int i = head[x]; i; i = Next[i]) {
        if((i & 1) == op) continue;
        int y = ver[i];
        check(y, flag, op);
    }
}

int dis[N], tot[N];
bool v[N];
void spfa(int n) {
    memset(dis, ~0x7f, sizeof dis), dis[1] = 0;
    queue<int> q;
    q.push(1), v[1] = 1;

    while(q.size()) {
        int x = q.front();
        q.pop(), v[x] = 0;

        for(int i = head[x]; i; i = Next[i]) {
            int y = ver[i], val = edge[i];
            if(dis[y] < dis[x] + val) {
                dis[y] = dis[x] + val;
                if(!v[y]) q.push(y), tot[y]++, v[y] = 1;
                if(tot[y] > n) puts("-1"), exit(0);
            }
        }
    }
    if(dis[n] < 0) puts("-1"), exit(0);
}

void clear() {
    memset(head, 0, sizeof head);
    memset(Next, 0, sizeof Next);
    memset(ver, 0, sizeof ver);
    cnt = 0;
}

bool is[N];
int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; i++) {
        scanf("%d %d", &e[i].x, &e[i].y);
        Add(e[i].x, e[i].y);
    }
    check(1, v1, 1), check(n, v2, 0);
    for(int i = 1; i <= n; i++)
        if(v1[i] && v2[i]) is[i] = 1;

    is[1] = is[n] = 1;
    clear();
    for(int i = 1; i <= m; i++) {
        if(is[e[i].x] && is[e[i].y]) {
            add(e[i].x, e[i].y, 1);
            add(e[i].y, e[i].x, -9);
        }
    }
    spfa(n);
    printf("%d %d\n", n, m);
    for(int i = 1; i <= m; i++) {
        printf("%d %d ", e[i].x, e[i].y);
        if(is[e[i].x] && is[e[i].y])
            printf("%d\n", dis[e[i].y] - dis[e[i].x]);
        else printf("1\n");
    }
    return 0;
}

Written on the back

At that time I did not write the exam brain pumping out, and then because of that \ (op \) to change an afternoon ......

Knelt \ (Orz \)

Guess you like

Origin www.cnblogs.com/Ning-H/p/11668193.html