Submission #762479

# Submission time Handle Problem Language Result Execution time Memory
762479 2023-06-21T12:30:08 Z LucaIlie Min-max tree (BOI18_minmaxtree) C++17
36 / 100
1000 ms 19684 KB
#include <bits/stdc++.h>

using namespace std;

struct query {
    int u, v, w;

    bool operator < ( const query &q ) const {
        return w < q.w;
    }
};

const int MAX_N = 7e4 + 1;
const int MAX_LOG_N = 16;
const int undef = -1;
bool used[MAX_N];
int depth[MAX_N], parent[MAX_LOG_N + 1][MAX_N], asc[MAX_N], queryMin[MAX_N], queryMax[MAX_N], value[MAX_N];
vector<int> edges[MAX_N];
vector<query> mins, maxs;

void dfs( int u, int p ) {
    depth[u] = depth[p] + 1;
    parent[0][u] = p;
    for ( int v: edges[u] ) {
        if ( v == p )
            continue;
        dfs( v, u );
    }
}

int lca( int u, int v ) {
    if ( depth[u] > depth[v] )
        swap( u, v );
    for ( int p = MAX_LOG_N; p >= 0; p-- ) {
        if ( depth[parent[p][v]] >= depth[u] )
            v = parent[p][v];
    }
    if ( u == v )
        return u;
    for ( int p = MAX_LOG_N; p >= 0; p-- ) {
        if ( parent[p][u] != parent[p][v] ) {
            u = parent[p][u];
            v = parent[p][v];
        }
    }
    return parent[0][v];
}

void init( int n ) {
    for ( int p = 1; p <= MAX_LOG_N; p++ ) {
        for ( int u = 1; u <= n; u++ )
            parent[p][u] = parent[p - 1][parent[p - 1][u]];
    }
}

struct MATCH {
    const int MULT = (1 << 30);
    const int NIL = 0;

    int n, m;
    int pairU[MAX_N + 1], pairV[MAX_N + 1], dist[MAX_N + 1];
    vector <int> edges[MAX_N + 1];

    void init( int _n, int _m ) {
        n = _n;
        m = _m;
    }

    void add_edge( int u, int v ) {
        //printf( "edge %d %d\n", u, v );
        edges[u].push_back( v );
    }

    bool bfs() {
        int u;
        queue <int> q;

        dist[NIL] = MULT;
        for ( u = 1; u <= n; u++ ) {
            if ( pairU[u] == NIL ) {
                dist[u] = 0;
                q.push( u );
            } else
                dist[u] = MULT;
        }

        while ( !q.empty() ) {
            u = q.front();
            q.pop();

            if ( dist[u] < dist[NIL] ) {
                for ( int v: edges[u] ) {
                    if ( dist[pairV[v]] == MULT ) {
                        dist[pairV[v]] = dist[u] + 1;
                        q.push( pairV[v] );
                    }
                }
            }
        }

        return dist[NIL] != MULT;
    }

    bool dfs( int u ) {
        if ( u == NIL )
            return true;

        for ( int v: edges[u] ) {
            if ( dist[pairV[v]] == dist[u] + 1 && dfs( pairV[v] ) ) {
                pairU[u] = v;
                pairV[v] = u;
                return true;
            }
        }

        dist[u] = MULT;

        return false;
    }

    void maxMatch() {
        int maxMatch, u, v;

        for ( u = 0; u <= n; u++ )
            pairU[u] = NIL;
        for ( v = 0; v <= m; v++ )
            pairV[v] = NIL;


        while ( bfs() ) {
            for ( u = 1; u <= n; u++ ) {
                if ( pairU[u] == NIL )
                    dfs( u );
            }
        }

        /*printf( "aici\n" );
        for ( int u = 1; u <= n; u++ )
            printf( "%d %d\n", u, pairU[u] );
        printf( "\n" );*/
    }
};

MATCH match;

int main() {
    int n, k;

    cin >> n;
    for ( int i = 0; i < n - 1; i++ ) {
        int u, v;
        cin >> u >> v;
        edges[u].push_back( v );
        edges[v].push_back( u );
    }

    dfs( 1, 0 );
    init( n );

    cin >> k;
    for ( int i = 0; i < k; i++ ) {
        char ch;
        int u, v, w;
        cin >> ch >> u >> v >> w;
        if ( ch == 'm' )
            mins.push_back( { u, v, w } );
        else
            maxs.push_back( { u, v, w } );
    }

    sort( mins.begin(), mins.end() );
    reverse( mins.begin(), mins.end() );
    for ( int u = 1; u <= n; u++ ) {
        asc[u] = parent[0][u];
        queryMin[u] = undef;
        used[u] = false;
    }
    for ( int i = 0; i < mins.size(); i++ ) {
        int u = mins[i].u, v = mins[i].v;
        int l = lca( u, v );
        while ( depth[u] > depth[l] ) {
            if ( !used[u] ) {
                used[u] = true;
                queryMin[u] = i;
            }
            u = parent[0][u];
        }
        while ( depth[v] > depth[l] ) {
            if ( !used[v] ) {
                used[v] = true;
                queryMin[v] = i;
            }
            v = parent[0][v];
        }
    }

    sort( maxs.begin(), maxs.end() );
    for ( int u = 1; u <= n; u++ ) {
        asc[u] = parent[0][u];
        queryMax[u] = undef;
        used[u] = false;
    }
    for ( int i = 0; i < maxs.size(); i++ ) {
        int u = maxs[i].u, v = maxs[i].v;
        int l = lca( u, v );

        while ( depth[u] > depth[l] ) {
            if ( !used[u] ) {
                used[u] = true;
                queryMax[u] = i;
            }
            u = parent[0][u];
        }
        while ( depth[v] > depth[l] ) {
            if ( !used[v] ) {
                used[v] = true;
                queryMax[v] = i;
            }
            v = parent[0][v];
        }
    }

    //for ( int u = 2; u <= n; u++ )
        //printf( "%d %d\n", queryMin[u], queryMax[u] );

    match.init( k, n - 1 );
    for ( int u = 2; u <= n; u++ ) {
        if ( queryMin[u] != -1 )
            match.add_edge( queryMin[u] + 1, u - 1 );
        if ( queryMax[u] != -1 )
            match.add_edge( mins.size() + queryMax[u] + 1, u - 1 );
    }
    match.maxMatch();

    for ( int u = 2; u <= n; u++ )
        value[u] = undef;
    for ( int i = 0; i < mins.size(); i++ )
        value[match.pairU[i + 1] + 1] = mins[i].w;
    for ( int i = 0; i < maxs.size(); i++ )
        value[match.pairU[mins.size() + i + 1] + 1] = maxs[i].w;

    for ( int u = 2; u <= n; u++ ) {
        if ( value[u] == undef ) {
            if ( queryMin[u] != undef )
                value[u] = mins[queryMin[u]].w;
            else if ( queryMax[u] != undef )
                value[u] = maxs[queryMax[u]].w;
            else
                value[u] = 0;
        }
        cout << u << " " << parent[0][u] << " " << value[u] << "\n";
    }

    return 0;
}

Compilation message

minmaxtree.cpp: In member function 'void MATCH::maxMatch()':
minmaxtree.cpp:122:13: warning: unused variable 'maxMatch' [-Wunused-variable]
  122 |         int maxMatch, u, v;
      |             ^~~~~~~~
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:178:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  178 |     for ( int i = 0; i < mins.size(); i++ ) {
      |                      ~~^~~~~~~~~~~~~
minmaxtree.cpp:203:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  203 |     for ( int i = 0; i < maxs.size(); i++ ) {
      |                      ~~^~~~~~~~~~~~~
minmaxtree.cpp:237:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  237 |     for ( int i = 0; i < mins.size(); i++ )
      |                      ~~^~~~~~~~~~~~~
minmaxtree.cpp:239:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  239 |     for ( int i = 0; i < maxs.size(); i++ )
      |                      ~~^~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 3668 KB Output is correct
2 Correct 3 ms 3668 KB Output is correct
3 Correct 2 ms 3600 KB Output is correct
4 Correct 3 ms 3596 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 144 ms 19308 KB Output is correct
2 Correct 146 ms 19684 KB Output is correct
3 Execution timed out 1091 ms 15644 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 102 ms 14916 KB Output is correct
2 Correct 86 ms 15984 KB Output is correct
3 Correct 79 ms 17572 KB Output is correct
4 Correct 90 ms 18284 KB Output is correct
5 Correct 97 ms 16368 KB Output is correct
6 Correct 104 ms 16808 KB Output is correct
7 Correct 94 ms 16252 KB Output is correct
8 Correct 115 ms 16136 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 3668 KB Output is correct
2 Correct 3 ms 3668 KB Output is correct
3 Correct 2 ms 3600 KB Output is correct
4 Correct 3 ms 3596 KB Output is correct
5 Correct 144 ms 19308 KB Output is correct
6 Correct 146 ms 19684 KB Output is correct
7 Execution timed out 1091 ms 15644 KB Time limit exceeded
8 Halted 0 ms 0 KB -