제출 #78906

#제출 시각아이디문제언어결과실행 시간메모리
78906bogdan10bosMin-max tree (BOI18_minmaxtree)C++14
100 / 100
218 ms89396 KiB
#include <bits/stdc++.h>

using namespace std;

//#define FILE_IO

typedef pair<int, int> pii;
typedef pair<pii, int> p3i;

const int NMAX = 70005;

p3i chn[NMAX];
int N, E, K;
int h[NMAX], f[NMAX], eul[NMAX], lg2[2 * NMAX], rmq[18][2 * NMAX];
int st[NMAX], dr[NMAX], c[NMAX], up[NMAX];
vector<int> chnmn, chnmx, edg[NMAX];

void DFS(int nod, int fth)
{
    f[nod] = fth;
    h[nod] = h[fth] + 1;
    rmq[0][++E] = nod;
    eul[nod] = E;
    for(auto nxt: edg[nod])
        if(nxt != fth)
        {
            DFS(nxt, nod);
            rmq[0][++E] = nod;
        }
}

int minh(int a, int b) { return (h[a] < h[b] ? a : b); }
int LCA(int a, int b)
{
    int pa = eul[a], pb = eul[b];
    if(pa > pb) swap(pa, pb);
    int lg = lg2[pb - pa + 1];
    return minh(rmq[lg][pa], rmq[lg][pb - (1 << lg) + 1]);
}

int Up(int x) { if(up[x] == x) return x; return up[x] = Up(up[x]); }

void color(int x, int y, int val)
{
    x = Up(x); y = Up(y);
    while(x != y)
    {
        c[x] = val;
        up[x] = Up(f[x]);
        x = Up(x);
    }
}

namespace Matching
{
    int N, F;
    int node[2 * NMAX];
    int mtc[2 * NMAX], f[2 * NMAX];
    vector<int> edg[2 * NMAX];

    void setN(int _N) { N = _N; }

    void addEdge(int x, int y)
    {
        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    int match(int x)
    {
        if(f[x] == F)   return 0;
        f[x] = F;

        for(auto nxt: edg[x])
            if(!mtc[nxt])
            {
                mtc[nxt] = x;
                mtc[x] = nxt;
                return 1;
            }
        for(auto nxt: edg[x])
            if( match(mtc[nxt]) )
            {
                mtc[nxt] = x;
                mtc[x] = nxt;
                return 1;
            }

        return 0;
    }

    void randomize()
    {
        mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
        for(int i = 1; i <= N; i++)
            shuffle(edg[i].begin(), edg[i].end(), gen);
        for(int i = 1; i <= N; i++) node[i] = i;
        shuffle(node + 1, node + N + 1, gen);
    }

    void solve()
    {
        randomize();
        bool newm = true;
        F = 0;
        while(newm)
        {
            F++;
            newm = false;
            for(int i = 1; i <= N; i++)
                if(!mtc[ node[i] ])
                    if( match(node[i]) )
                        newm = true;
        }
    }
}

int main()
{
    #ifdef FILE_IO
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    #endif

    scanf("%d", &N);
    for(int i = 1; i < N; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    DFS(1, 0);
    for(int i = 2; i <= E; i++) lg2[i] = 1 + lg2[i >> 1];
    for(int i = 1; (1 << i) <= E; i++)
        for(int j = 1; j + (1 << i) - 1 <= E; j++)
            rmq[i][j] = minh(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);

    scanf("%d\n", &K);
    for(int i = 1; i <= K; i++)
    {
        char ch;
        int x, y, val;
        scanf("%c %d%d%d\n", &ch, &x, &y, &val);
        chn[i] = { {x, y}, val };
        if(ch == 'm')   chnmn.push_back(i);
        else if(ch == 'M')  chnmx.push_back(i);
    }

    sort(chnmn.begin(), chnmn.end(),
         [](int a, int b) { return chn[a].second > chn[b].second; });
    sort(chnmx.begin(), chnmx.end(),
         [](int a, int b) { return chn[a].second < chn[b].second; });

    Matching::setN(N + K);

    for(int i = 1; i <= N; i++) up[i] = i, c[i] = 0;
    for(auto id: chnmn)
    {
        int x = chn[id].first.first, y = chn[id].first.second;
        int val = chn[id].second;
        int lca = LCA(x, y);
        color(x, lca, id);
        color(y, lca, id);
    }
    for(int i = 1; i <= N; i++)
        if(c[i] != 0)
            Matching::addEdge(i, c[i] + N);

    for(int i = 1; i <= N; i++) up[i] = i, c[i] = 0;
    for(auto id: chnmx)
    {
        int x = chn[id].first.first, y = chn[id].first.second;
        int val = chn[id].second;
        int lca = LCA(x, y);
        color(x, lca, id);
        color(y, lca, id);
    }
    for(int i = 1; i <= N; i++)
        if(c[i] != 0)
            Matching::addEdge(i, c[i] + N);

    Matching::solve();

    for(int i = 2; i <= N; i++)
    {
        if(Matching::mtc[i] != 0)
        {
            int ch = Matching::mtc[i] - N;
            printf("%d %d %d\n", f[i], i, chn[ch].second);
        }
        else
        {
            int val = 42;
            if(!Matching::edg[i].empty())   val = chn[ Matching::edg[i][0] - N ].second;
            printf("%d %d %d\n", f[i], i, val);
        }
    }


    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:162:13: warning: unused variable 'val' [-Wunused-variable]
         int val = chn[id].second;
             ^~~
minmaxtree.cpp:175:13: warning: unused variable 'val' [-Wunused-variable]
         int val = chn[id].second;
             ^~~
minmaxtree.cpp:125:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &N);
     ~~~~~^~~~~~~~~~
minmaxtree.cpp:129:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d", &x, &y);
         ~~~~~^~~~~~~~~~~~~~~~
minmaxtree.cpp:140:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d\n", &K);
     ~~~~~^~~~~~~~~~~~
minmaxtree.cpp:145:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%c %d%d%d\n", &ch, &x, &y, &val);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...