답안 #209597

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
209597 2020-03-14T18:35:00 Z nicolaalexandra Min-max tree (BOI18_minmaxtree) C++14
7 / 100
286 ms 54008 KB
#include <bits/stdc++.h>
#define DIM 70010
using namespace std;
int level[DIM],fth[DIM],Left[DIM],Right[DIM];
int E[DIM*4],p[DIM*4],first[DIM],viz[DIM],tata[DIM],dp_min[DIM],dp_max[DIM];
pair <int,int> rmq[30][DIM];
vector <int> L[DIM],edg[DIM];
struct _update{
    int tip,x,y,val;
};
_update v[DIM],w[DIM];
map <int,int> poz;
int n,m,i,j,x,y,val,dist,lca,k,tip,el,ok,idx;
char ch;

void dfs (int nod, int father){
    E[++k] = nod;
    first[nod] = k;
    level[nod] = 1 + level[father];
    fth[nod] = tata[nod] = father;
    for (int i=0;i<L[nod].size();i++){
        int vecin = L[nod][i];
        if (vecin != father){
            dfs (vecin,nod);
            E[++k] = nod;
        }}}

int get_lca (int x, int y){
    int posx = first[x], posy = first[y];
    if (posx > posy)
        swap (posx,posy);
    int nr = p[posy-posx+1];
    pair <int,int> sol = min (rmq[nr][posx],rmq[nr][posy-(1<<nr)+1]);
    return E[sol.second];
}

inline int cmp (_update a, _update b){
    return a.val < b.val;
}

int cupleaza (int nod){
    if (viz[nod])
        return 0;

    viz[nod] = 1;
    for (auto vecin : edg[nod]){
        if (Right[vecin] == 0){
            Left[nod] = vecin;
            Right[vecin] = nod;
            return 1;
        } }

    for (auto vecin : edg[nod]){
        if (cupleaza(Right[vecin])){
            Left[nod] = vecin;
            Right[vecin] = nod;
            return 1;
        }}

    return 0;
}

int main (){

  //  ifstream cin ("minmaxtree.in");
  //  ofstream cout ("minmaxtree.out");

    cin>>n;
    for (i=1;i<n;i++){
        cin>>x>>y;
        L[x].push_back(y);
        L[y].push_back(x);
    }
    dfs (1,0);

    for (i=1;i<=k;i++)
        rmq[0][i] = make_pair (level[E[i]],i);

    for (i=1;(1<<i)<=k;i++){
        for (j=1;j<=k;j++){
            rmq[i][j] = rmq[i-1][j];
            if (j + (1<<(i-1)) <= k && rmq[i-1][j + (1<<(i-1))].first < rmq[i][j].first)
                rmq[i][j] = rmq[i-1][j + (1<<(i-1))];
        }}

    for (i=2;i<=k;i++)
        p[i] = p[i/2] + 1;

    cin>>m;
    for (i=1;i<=m;i++){
        cin>>ch>>x>>y>>val;
        if (ch == 'M')
            tip = 1;
        else tip = 0;

        v[i] =  {tip,x,y,val};

        poz[val] = i;

        if (tip)
            w[++el] = v[i];
    }

    /// dp_min[nod] - minimul valorilor de maxim care trec prin muchia nod-fth[nod]

    sort (w+1,w+el+1,cmp);
    for (i=1;i<=el;i++){
        int x = w[i].x, y = w[i].y, val = w[i].val;
        lca = get_lca (x,y);

        /// acum incerc sa fac toate valorile nemcacate de pe drumul de la x la lca egale cu val
        int nod = x;
        while (level[nod] > level[lca]){

            if (!dp_min[nod]){
                dp_min[nod] = val;

                for (auto vecin : L[nod]){
                    if (vecin != tata[nod])
                        fth[vecin] = lca;
                }
            }

            nod = fth[nod];
        }


        nod = y;
        while (level[nod] > level[lca]){

            if (!dp_min[nod]){
                dp_min[nod] = val;

                for (auto vecin : L[nod]){
                    if (vecin != tata[nod])
                        fth[vecin] = lca;
                }
            }

            nod = fth[nod];
        }
    }


    for (i=1;i<=n;i++)
        fth[i] = tata[i];

    /// acum facem dp_max

    el = 0;
    for (i=1;i<=n;i++){
        if (v[i].tip == 0)
            w[++el] = v[i];
    }
    sort (w+1,w+el+1,cmp);

    for (i=el;i;i--){
        int x = w[i].x, y = w[i].y, val = w[i].val;
        lca = get_lca (x,y);

        /// acum incerc sa fac toate valorile nemcacate de pe drumul de la x la lca egale cu val
        int nod = x;
        while (level[nod] > level[lca]){

            if (!dp_max[nod]){
                dp_max[nod] = val;

                for (auto vecin : L[nod]){
                    if (vecin != tata[nod])
                        fth[vecin] = lca;
                }
            }

            nod = fth[nod];
        }


        nod = y;
        while (level[nod] > level[lca]){

            if (!dp_max[nod]){
                dp_max[nod] = val;

                for (auto vecin : L[nod]){
                    if (vecin != tata[nod])
                        fth[vecin] = lca;
                }
            }

            nod = fth[nod];
        }

    }

    /// acum trb sa stabilesc pt fiecare nod daca sa aleg dp_max sau dp_min
    /// si fiecare valoare din input trb sa apara cel putin odata

    for (i=1;i<=n;i++){
        if (dp_max[i]){
            idx = poz[dp_max[i]];

            edg[i].push_back (n + idx);
            edg[n + idx].push_back (i);
        }

        if (dp_min[i]){
            idx = poz[dp_min[i]];

            edg[i].push_back(n + idx);
            edg[n + idx].push_back(i);
        }

    }


    do{
        memset (viz,0,sizeof viz);
        ok = 0;
        for (i=1;i<=n;i++){
            if (!Left[i] && cupleaza(i))
                ok = 1;
        }
    } while (ok);

    //for (i=2;i<=n;i++)
      //  cout<<dp_max[i]<<" "<<dp_min[i]<<endl;

    for (i=2;i<=n;i++){
        cout<<i<<" "<<tata[i]<<" ";
        int idx = Left[i];
        cout<<v[idx - n].val<<"\n";
    }



    return 0;
}

Compilation message

minmaxtree.cpp: In function 'void dfs(int, int)':
minmaxtree.cpp:21:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i=0;i<L[nod].size();i++){
                  ~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 3960 KB Output is correct
2 Correct 7 ms 3960 KB Output is correct
3 Correct 7 ms 3960 KB Output is correct
4 Correct 7 ms 3832 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 286 ms 54008 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 182 ms 45560 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 3960 KB Output is correct
2 Correct 7 ms 3960 KB Output is correct
3 Correct 7 ms 3960 KB Output is correct
4 Correct 7 ms 3832 KB Output is correct
5 Runtime error 286 ms 54008 KB Execution killed with signal 11 (could be triggered by violating memory limits)
6 Halted 0 ms 0 KB -