洛谷P2475 [SCOI2008]斜堆——题解

题目传送门
题目大意:
看题面吧。


思考过程&具体做法:
当前插入的是极左没有右儿子的节点,也就是一直往左走直至一个没有右儿子的点停止,然后删掉他交换父节点的左右儿子,这样做是符合的,但为什么最优不会证2333。


代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn=60;
int root,n;
int c[maxn][2],ans[maxn],fa[maxn];

void work()
{
    int cnt=n+1,p,f,son,fl;
    while(cnt)
    {
        fl=0,p=root;
        while(c[p][1]!=-1) p=c[p][0];
        son=c[p][0];
        if(son!=-1&&c[son][0]==-1&&c[son][1]==-1) p=son;
        ans[cnt--]=p;
        f=fa[p],son=c[p][0];
        if(p==root) root=son,fl=1,fa[son]=-1;
        else if(son!=-1) c[f][0]=son,fa[son]=f;
        else c[f][0]=-1;
        while(p!=root&&!fl)
        {
            p=fa[p];
            swap(c[p][0],c[p][1]);  
        }
    }
}

int main()
{
    memset(c,-1,sizeof(c));
    memset(fa,-1,sizeof(fa));
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        if(x<100) c[fa[i]=x][0]=i;
        else c[fa[i]=x-100][1]=i;   
    }
    root=0;
    work();
    for(int i=1;i<=n+1;i++) printf("%d ",ans[i]);
    printf("\n");
    return 0;   
}

猜你喜欢

转载自blog.csdn.net/qq_39662197/article/details/80176830