Submission #61516

# Submission time Handle Problem Language Result Execution time Memory
61516 2018-07-26T06:22:57 Z 강태규(#1777) Min-max tree (BOI18_minmaxtree) C++11
29 / 100
1000 ms 18320 KB
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <functional>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>

using namespace std;
typedef long long llong;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<llong, llong> pll;

int n;
const int inf = 1e9 + 7;

struct query {
    int x, y, z;
    char scan() {
        static char in[10];
        scanf("%s%d%d%d", in, &x, &y, &z);
        return *in;
    }
};

vector<int> edge[70001];
vector<query> qs[256];
int par[70001][17];
int nxt[70001];
int dep[70001];

void dfs(int x, int p) {
    par[x][0] = p;
    dep[x] = dep[p] + 1;
    for (int i = 1; i < 17; ++i) {
        par[x][i] = par[par[x][i - 1]][i - 1];
    }
    for (int i : edge[x]) {
        if (i == p) continue;
        dfs(i, x);
    }
}

int lca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    for (int i = 17; i--; ) {
        if ((dep[x] - dep[y]) >> i) x = par[x][i];
    }
    if (x == y) return x;
    for (int i = 17; i--; ) {
        if (par[x][i] != par[y][i]) {
            x = par[x][i];
            y = par[y][i];
        }
    }
    return par[x][0];
}

int mn[70001];
int mx[70001];

int paint(int c[], int s, int e, int x) {
    if (dep[s] <= dep[e]) return s;
    if (c[s]) nxt[s] = paint(c, nxt[s], e, x);
    c[s] = x;
    return nxt[s] = paint(c, par[s][0], e, x);
}

int find(vector<int> &v, int x) {
    return lower_bound(v.begin(), v.end(), x) - v.begin();
}

struct matching {
    vector<int> edge[70001];
    int mat[70001];
    int rev[70001];
    int visited[70001];
    int lv[70001];
    int n;
    
    void bfs() {
        queue<int> q;
        for (int i = 2; i <= n; ++i) {
            if (visited[i]) lv[i] = inf;
            else lv[i] = 0, q.push(i);
        }
        
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i : edge[x]) {
                if (rev[i]) {
                    if (lv[rev[i]] < inf) continue;
                    lv[rev[i]] = lv[x] + 1;
                    q.push(rev[i]);
                }
            }
        }
    }
    
    int dfs(int x) {
        for (int i : edge[x]) {
            if (rev[i] == 0 || lv[rev[i]] == lv[x] + 1 && dfs(rev[i])) {
                visited[x] = 1;
                mat[x] = i;
                rev[i] = x;
                return 1;
            }
        }
        return 0;
    }
    
    int process(int N) {
        n = N;
        int ret = 0;
        while (1) {
            bfs();
            int res = 0;
            for (int i = 2; i <= n; ++i) {
                if (visited[i]) continue;
                res += dfs(i);
            }
            if (res == 0) break;
            ret += res;
        }
        return ret;
    }
} mt;

int main() {
    scanf("%d", &n);
    for (int i = 1; i < n; ++i) {
        int a, b;
        scanf("%d%d", &a, &b);
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    dfs(1, 0);
    int k;
    scanf("%d", &k);
    vector<int> cp;
    for (int i = 0; i < k; ++i) {
        query q;
        char c = q.scan();
        qs[c].push_back(q);
        cp.push_back(q.z);
    }
    cp.push_back(0);
    sort(cp.begin(), cp.end());
    cp.erase(unique(cp.begin(), cp.end()), cp.end());
    
    sort(qs['m'].begin(), qs['m'].end(), [&](const query &x, const query &y) {
        return x.z > y.z;
    });
    sort(qs['M'].begin(), qs['M'].end(), [&](const query &x, const query &y) {
        return x.z < y.z;
    });
    
    for (query i : qs['m']) {
        int p = lca(i.x, i.y);
        paint(mn, i.x, p, i.z);
        paint(mn, i.y, p, i.z);
    }
    
    for (query i : qs['M']) {
        int p = lca(i.x, i.y);
        paint(mx, i.x, p, i.z);
        paint(mx, i.y, p, i.z);
    }
    
    for (int i = 2; i <= n; ++i) {
        if (mn[i]) mt.edge[i].push_back(find(cp, mn[i]));
        if (mx[i]) mt.edge[i].push_back(find(cp, mx[i]));
    }
    
    mt.process(n);
    
    for (int i = 1; i < cp.size(); ++i) {
        mn[mt.rev[i]] = cp[i];
    }
    
    for (int i = 2; i <= n; ++i) {
        printf("%d %d %d\n", i, par[i][0], mn[i]);
    }
    
	return 0;
}

Compilation message

minmaxtree.cpp: In member function 'int matching::dfs(int)':
minmaxtree.cpp:110:56: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
             if (rev[i] == 0 || lv[rev[i]] == lv[x] + 1 && dfs(rev[i])) {
                                ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:152:13: warning: array subscript has type 'char' [-Wchar-subscripts]
         qs[c].push_back(q);
             ^
minmaxtree.cpp:185:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 1; i < cp.size(); ++i) {
                     ~~^~~~~~~~~~~
minmaxtree.cpp:138:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
     ~~~~~^~~~~~~~~~
minmaxtree.cpp:141:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d", &a, &b);
         ~~~~~^~~~~~~~~~~~~~~~
minmaxtree.cpp:147:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &k);
     ~~~~~^~~~~~~~~~
minmaxtree.cpp: In member function 'char query::scan()':
minmaxtree.cpp:28:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%s%d%d%d", in, &x, &y, &z);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 3708 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 1073 ms 14752 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 134 ms 16004 KB Output is correct
2 Correct 228 ms 16096 KB Output is correct
3 Correct 162 ms 17616 KB Output is correct
4 Correct 135 ms 18320 KB Output is correct
5 Correct 151 ms 18320 KB Output is correct
6 Correct 169 ms 18320 KB Output is correct
7 Correct 178 ms 18320 KB Output is correct
8 Correct 186 ms 18320 KB Output is correct
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 3708 KB Output isn't correct
2 Halted 0 ms 0 KB -