• 【洛谷P4934】 礼物,拓扑排序


    题目大意:给你$n$个不重复的数,其值域为$[0,2^k)$,问你至少需要将这$n$个数拆成多少个集合,使得它们互相不是对方的子集,并输出方案。

    数据范围:$n≤10^6$,$k≤20$。

    $MD$我场上都想了啥。。。。

    我们显然有一种$O(3^k)$的做法,对于数字$x$,我们枚举其子集,设当前枚举到的子集为$u$,我们连一条$u->x$的边,然后跑一个拓扑排序,即可确定至少需要划分为多少个集合(我场上根本没在想拓扑排序。。。。)

    然后,这个显然会$TLE+MLE$。

    然后我们发现,若存在$u,v,w,$满足$u$是$v$的子集,$v$是$w$的子集,那么这种情况下,从$w$连边向$u$,其实是多余的。故对于数字$x$,我们只需要连接$u->x$,其中$u$^$x=2^p$。那么边的数量就成功降低至$2^k$。

    时间复杂度:$O(nk)$。

     1 #include<bits/stdc++.h>
     2 #define M 1100005
     3 using namespace std;
     4 struct edge{int u,next;}e[M*20]={0}; int head[M]={0},use=0;
     5 void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
     6 int n,k,id[M]={0};
     7 queue<int> q; int dfn[M]={0},in[M]={0};
     8 int main(){
     9     scanf("%d%d",&n,&k);
    10     for(int i=1;i<=n;i++){
    11         int x; scanf("%d",&x);
    12         id[x]=i;
    13     }
    14     for(int i=0;i<(1<<k);i++){
    15         for(int j=0;j<k;j++)
    16         if((i&(1<<j))==0) add(i,i^(1<<j)),in[i^(1<<j)]++;
    17     }
    18     q.push(0);
    19     while(!q.empty()){
    20         int u=q.front(); q.pop();
    21         if(id[u]) dfn[u]++;
    22         for(int i=head[u];i;i=e[i].next){
    23             in[e[i].u]--; 
    24             dfn[e[i].u]=max(dfn[e[i].u],dfn[u]);
    25             if(in[e[i].u]==0) q.push(e[i].u);
    26         }
    27     }
    28     cout<<1<<endl;
    29     cout<<dfn[(1<<k)-1]<<endl;
    30     
    31     for(int i=1;i<=dfn[(1<<k)-1];i++){
    32         int res=0;
    33         for(int j=0;j<(1<<k);j++) res+=(dfn[j]==i&&id[j]);
    34         printf("%d ",res);
    35         for(int j=0;j<(1<<k);j++) if(dfn[j]==i&&id[j]) printf("%d ",j);
    36         printf("
    ");
    37     }
    38 }
  • 相关阅读:
    javascript 注意事项汇总
    Object.prototype.toString方法
    PHPStorm使用心得
    JavaScript基于原型链的继承
    PHP重定向的3种方式
    Android应用与开发环境
    PHP时间处理
    cocos2dxna 游戏中如何控制后退键实现目的性跳转
    wp7 独立存储空间在真机和虚拟机测试的时候数据不一样
    c#获取交叉数组的行、列数
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9826860.html
Copyright © 2020-2023  润新知