签到

06月21日
尚未签到

共有回帖数 0

    奈何情殇

    等级:
    Introduction to Algorithms 中的一道习题
    一个包含 n 个 insert 和 m 个 extract-min 操作的序列
    insert,插入一个数,这个数来自于域 (1,2,……,n},,保证每次插入的数互不相同
    extract-min,从当前插入且未删除的数中选择最小的输出,然后把这个数删除
    希望对一个数组 extracted[1..m] 进行填充,使得 extracted 存放第 i 次 extract-min 操作的结果

    比如:
    3,5,E,1,2,E,E,E,4,E(整数代表 insert 操作,E 表示 extract-min 操作)

    extracted[1..5] 应为
    3,1,2,5,4

    定义函数
    A[k](j) = j+1,若 k = 0
         A[k-1]^(j+1) (j),若 k  0
    定义函数
    α(n) = min{k : Ak(1) = n}

    该问题存在 Ο(nα(n)) 的算法,α(x) 是一个增长极为缓慢的函数,可以近似地看作 Ο(1)
    该算法可以近似地看作线性算法


    是啊

    #include algorithm
    #include cstdio
    using namespace std;

    const int N = 100;
    int a[N*2-1], b[N],
       id_name[N+1], name_id[N+1],
       prev[N+1], next[N+1],
       extracted[N], parent[N+1];

    int Find(int x)
    {
       return parent[x] = 0 ? parent[x] = Find(parent[x]) : x;
    }

    int Union(int x, int y)
    {
       if (parent[x]  parent[y])
           return parent[x] += parent[y], parent[y] = x, x;
       else
           return parent[y] += parent[x], parent[x] = y, y;
    }

    int main()
    {
       int m, n;
       scanf("%d%d", &n, &m);
       for (int cnt = m+n, i = 0, j = 0; cnt; --cnt)
       {
           scanf("%d", &a);
           if (a != -1)
               ++i;
           else
           {
               if (j && b[j-1] == i)
                   a[i++] = 0;
               b[j++] = i;
           }
       }
       fill_n(parent, n+1, -1);
       fill_n(name_id+1, n, m);
       id_name[m] = -1;
       for (int i = 0; i  m; ++i)
       {
           int curr = !i ? a[0] : b  b[i-1] ? a[b[i-1]] : -1;
           if (curr != -1)
           {
               for (int j = i ? b[i-1] : 0; ++j  b; )
                   curr = Union(curr, a[j]);
               name_id[curr] = i;
           }
           id_name = curr;
       }
       for (int i = 0; i  m; ++i)
           prev[i+1] = i, next = i+1;
       for (int i = 1; i = n; ++i)
       {
           int name = Find(i), id = name_id[name];
           if (id  m)
           {
               if (id_name[next[id]] != -1)
                   name = Union(name, id_name[next[id]]);
               name_id[name] = next[id];
               id_name[next[id]] = name;
               next[prev[id]] = next[id];
               prev[next[id]] = prev[id];
               extracted[id] = i;
           }
       }
       for (int i = 0; i  m; ++i)
           printf("%dn", extracted);
       return 0;
    }

    楼主 2015-12-31 12:59 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知