답안 #61521

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
61521 2018-07-26T06:47:58 Z 강태규(#1777) Min-max tree (BOI18_minmaxtree) C++11
0 / 100
1000 ms 14748 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 ans[70001];

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);
    }
    exit(1);
    
    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) {
        ans[mt.rev[i]] = cp[i];
    }
    
    for (int i = 2; i <= n; ++i) {
        printf("%d %d %d\n", i, par[i][0], ans[i] ? ans[i] : (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:154:13: warning: array subscript has type 'char' [-Wchar-subscripts]
         qs[c].push_back(q);
             ^
minmaxtree.cpp:188:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 1; i < cp.size(); ++i) {
                     ~~^~~~~~~~~~~
minmaxtree.cpp:140:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
     ~~~~~^~~~~~~~~~
minmaxtree.cpp:143: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:149: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);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Runtime error 6 ms 3576 KB Execution failed because the return code was nonzero
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1041 ms 14748 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 132 ms 14748 KB Execution failed because the return code was nonzero
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 6 ms 3576 KB Execution failed because the return code was nonzero
2 Halted 0 ms 0 KB -