@atcoder - AGC018F@ Two Trees


@description@

Given two trees A, B. You now need to construct a set of values ​​(X1, X2, ..., XN) (number two trees corresponding to the same point of the same weight), so that the weights of any two trees and subtrees of the absolute value of 1.

No solution output IMPOSSIBLE.

The original title link.

@solution@

Since weights and 1, you can calculate the parity of each node. If the two trees in the same node weights different parity no solution.

We are able to construct a set of solutions after considering the parity of each junction point of known weights.
Since it is a configuration problem, from simple principles, guess even point is always 0, the singularity is always 1 or -1.
Hand to play with the sample found to be right.

Then it corresponds to each singularity white to black, so that the number of black and white dots subtree each of them is a phase difference.

Then began fantasy up. We singularity for each i, between two trees A, the node B Ai, Bi an even edge.
At this point note that the new figures root degrees only two trees may be an odd number, so we ran Euler path from the root.
If the Eulerian path Ai-> Bi black dot i is (-1), or white point i (1).

Accuracy is not difficult to understand: for each communication block (sub-tree), into the communication generalized block "penetration" generalized "out degree" from the communication block are equal.
Whereas the subtree outwardly only two sides: even to his father (only one); connected to another tree. That is, even to the other side of the tree (the edge between the singular point) into a side edge and a difference of 1, construction is our goal.

@accepted code@

#include <cstdio>

const int MAXN = 200000;
const int MAXM = 8*MAXN;

struct edge{
    int to; bool tag;
    edge *nxt, *rev;
}edges[MAXM + 5], *adj[MAXN + 5], *ecnt = edges;

void addedge(int u, int v) {
    edge *p = (++ecnt), *q = (++ecnt);
    p->to = v, p->tag = false, p->nxt = adj[u], adj[u] = p;
    q->to = u, q->tag = false, q->nxt = adj[v], adj[v] = q;
    p->rev = q, q->rev = p;
}

int X[MAXN + 5], N;
void dfs(int x) {
    for(;adj[x];) {
        edge *p = adj[x]; adj[x] = adj[x]->nxt;
        if( p->tag ) continue;
        p->tag = p->rev->tag = true;
        dfs(p->to);
        if( x - p->to == -N ) X[x] = -1;
        else if( x - p->to == N ) X[p->to] = 1;
    }
}

int cnt[2][MAXN + 5];
int main() {
    scanf("%d", &N);
    int rt1;
    for(int i=1;i<=N;i++) {
        int x; scanf("%d", &x);
        if( x != -1 ) {
            addedge(x, i);
            cnt[0][x]++;
        }
        else rt1 = i;
    }
    for(int i=1;i<=N;i++) {
        int x; scanf("%d", &x);
        if( x != -1 ) {
            addedge(x + N, i + N);
            cnt[1][x]++;
        } 
    }
    for(int i=1;i<=N;i++) {
        if( (cnt[0][i] - cnt[1][i]) & 1 ) {
            puts("IMPOSSIBLE");
            return 0;
        }
        if( !(cnt[0][i] & 1) )
            addedge(i, N + i);
    }
    dfs(rt1);
    puts("POSSIBLE");
    for(int i=1;i<=N;i++)
        printf("%d%c", X[i], (i == N ? '\n' : ' '));
}

@details@

If found it more difficult than the network flow modeling something .jpg.
Indeed the AGC, it easily out of a question of human wisdom.

There is a small detail: the entire tree as a sub-tree, is not connected up to the father's side. Therefore we have a special discussion to prove it (but short certificate was out).

Guess you like

Origin www.cnblogs.com/Tiw-Air-OAO/p/12234568.html