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

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

数据范围:n106k20

 

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

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

然后,这个显然会TLE+MLE

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

时间复杂度: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("\n");
37     }
38 }
复制代码
posted @   AlphaInf  阅读(331)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2017-10-21 【NOIP2015提高组】Day2 T2 子串
2017-10-21 【NOIP2015提高组】Day2 T1 跳石头
2017-10-21 【NOIP2015提高组】 Day1 T3 斗地主
2017-10-21 【NOIP2015提高组】 Day1 T2 信息传递
2017-10-21 【NOIP2015提高组】Day1 t1神奇的幻方
点击右上角即可分享
微信分享提示