답안 #226793

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
226793 2020-04-25T10:54:42 Z Andrei_Cotor Min-max tree (BOI18_minmaxtree) C++11
36 / 100
820 ms 262148 KB
#include<fstream>
#include<iostream>
#include<vector>
#include<set>
#include<map>
 
using namespace std;
 
vector<int> Adj[70005];
vector<pair<int,int> > Min[70005],Max[70005];
int Niv[70005],P[20][70005];
 
int getlca(int x, int y)
{
    if(Niv[x]>Niv[y])
        swap(x,y);
 
    for(int i=16; i>=0; i--)
    {
        if(Niv[P[i][y]]>=Niv[x])
            y=P[i][y];
    }
 
    if(x==y)
        return x;
 
    for(int i=16; i>=0; i--)
    {
        if(P[i][x]!=P[i][y])
        {
            x=P[i][x];
            y=P[i][y];
        }
    }
 
    return P[0][x];
}
 
void dfs(int nod, int p)
{
    Niv[nod]=1+Niv[p];
    P[0][nod]=p;
    for(auto other:Adj[nod])
    {
        if(other==p)
            continue;
        dfs(other,nod);
    }
}
 
int Mini[70005],Maxi[70005]; //val minima si maxima pe care o poate avea muchia
set<int> Smin[70005],Smax[70005];
int HPath[70005],Sz[70005],nr;
 
void getMaxiMini(int nod, int p)
{
    Sz[nod]=1;
    int mx=0;
    for(auto other:Adj[nod])
    {
        if(other==p)
            continue;
 
        getMaxiMini(other,nod);
 
        if(Sz[other]>Sz[mx])
            mx=other;
    }
 
    if(mx==0)
        HPath[nod]=++nr;
    else
        HPath[nod]=HPath[mx];
 
    for(auto other:Adj[nod])
    {
        if(other==p || other==mx)
            continue;
 
        for(auto el:Smin[HPath[other]])
            Smin[HPath[nod]].insert(el);
 
        for(auto el:Smax[HPath[other]])
            Smax[HPath[nod]].insert(el);
    }
 
    for(auto el:Min[nod])
    {
        if(el.second==-1)
            Smin[HPath[nod]].erase(el.first);
        else
            Smin[HPath[nod]].insert(el.first);
    }
 
    for(auto el:Max[nod])
    {
        if(el.second==-1)
            Smax[HPath[nod]].erase(el.first);
        else
            Smax[HPath[nod]].insert(el.first);
    }
 
    if(!Smin[HPath[nod]].empty())
        Mini[nod]=*Smin[HPath[nod]].rbegin();
 
    if(!Smax[HPath[nod]].empty())
        Maxi[nod]=*Smax[HPath[nod]].begin();
}
 
vector<int> G[70005];
int Edge[70005],Value[70005];
int Viz[70005];
 
bool potr(int nod)
{
    if(Viz[nod])
        return 0;
    
    Viz[nod]=1;
    for(auto edge:G[nod])
    {
        if(!Value[edge])
        {
            Value[edge]=nod;
            Edge[nod]=edge;
            return 1;
        }
    }
 
    for(auto edge:G[nod])
    {
        if(potr(Value[edge]))
        {
            Value[edge]=nod;
            Edge[nod]=edge;
            return 1;
        }
    }
    return 0;
}
 
map<int,int> Ind;
int Rez[70005];
 
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cout.tie(0);
    int n;
    cin>>n;
    for(int i=1; i<n; i++)
    {
        int x,y;
        cin>>x>>y;
 
        Adj[x].push_back(y);
        Adj[y].push_back(x);
    }
 
    dfs(1,0);
    for(int i=1; i<=16; i++)
    {
        for(int j=1; j<=n; j++)
        {
            P[i][j]=P[i-1][P[i-1][j]];
        }
    }
            
    int m;
    cin>>m;
    for(int i=1; i<=m; i++)
    {
        char tip;
        int x,y,val;
        cin>>tip>>x>>y>>val;
 
        if(tip=='m')
        {
            int lca=getlca(x,y);
 
            if(x!=lca)
                Min[x].push_back({val,1});
            if(y!=lca)
                Min[y].push_back({val,1});
            Min[lca].push_back({val,-1});
        }
        else
        {
            int lca=getlca(x,y);
 
            if(x!=lca)
                Max[x].push_back({val,1});
            if(y!=lca)
                Max[y].push_back({val,1});
            Max[lca].push_back({val,-1});
        }
 
        Ind[val]=i;
    }
 
    getMaxiMini(1,0);
 
    for(int i=2; i<=n; i++)
    {
        if(Mini[i]!=0)
            G[Ind[Mini[i]]].push_back(i);
 
        if(Maxi[i]!=0)
            G[Ind[Maxi[i]]].push_back(i);
    }
 
    bool cont=1;
    while(cont)
    {
        cont=0;
        for(int i=1; i<=m; i++)
            Viz[i]=0;
 
        for(int i=1; i<=m; i++)
        {
            if(!Edge[i])
                cont|=potr(i);
        }
    }
 
    for(auto el:Ind)
    {
        Rez[Edge[el.second]]=el.first;
    }
 
    for(int i=2; i<=n; i++)
    {
        cout<<i<<" "<<P[0][i]<<" ";
 
        if(Rez[i])
            cout<<Rez[i]<<"\n";
        else
            cout<<Mini[i]<<"\n";
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 13568 KB Output is correct
2 Correct 12 ms 13568 KB Output is correct
3 Correct 12 ms 13696 KB Output is correct
4 Correct 12 ms 13568 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 357 ms 43204 KB Output is correct
2 Correct 380 ms 46076 KB Output is correct
3 Runtime error 820 ms 262148 KB Execution killed with signal 9 (could be triggered by violating memory limits)
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 167 ms 30572 KB Output is correct
2 Correct 159 ms 30712 KB Output is correct
3 Correct 141 ms 31992 KB Output is correct
4 Correct 143 ms 33912 KB Output is correct
5 Correct 172 ms 30584 KB Output is correct
6 Correct 181 ms 31352 KB Output is correct
7 Correct 175 ms 30072 KB Output is correct
8 Correct 174 ms 29944 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 13568 KB Output is correct
2 Correct 12 ms 13568 KB Output is correct
3 Correct 12 ms 13696 KB Output is correct
4 Correct 12 ms 13568 KB Output is correct
5 Correct 357 ms 43204 KB Output is correct
6 Correct 380 ms 46076 KB Output is correct
7 Runtime error 820 ms 262148 KB Execution killed with signal 9 (could be triggered by violating memory limits)
8 Halted 0 ms 0 KB -