maximum clique 1

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述

You are given a set S containing n distinct positive integers a1,a2,…,an.

Please find a subset of S which has the maximum size while satisfying the following constraint:

The binary representations of any two numbers in this subset must have at least two different bits.

If there are multiple valid subsets, please output any one of them.

输入描述:

The input contains only two lines.

The first line contains an integer N denoting the size of S.
The second line contains N positive integers a1,a2,…,aN​ denoting the members of set S. * 1≤N≤5000 * 1≤ai≤1e9 * all ai are distinct

输出描述:

You should output two lines.

The first line contains one integer m denoting the size of the subset you found.

The second line contains m positive integers denoting the member of this subset.

输入

5
3 1 4 2 5

输出

3
4 1 2

说明

3 (112) and 1 (012) has only 1 different bit so they can not be in the set together. 4 (1002) and 1 (0012) has 2 different bits so they can be in the set together.
Following unordered pairs are allowed to be in the set together: <1, 2>, <1, 4>, <2, 4>, <2, 5>, <3, 4>, <3, 5>. Thus the maximum set is of size 3 ({1, 2, 4}).

题意:在一个集合中求一个最大的子集,使得子集里任意两个数之间至少有两个二进制位不同。
思路:两个相异的数至少两个bit不一样的否命题是:恰一个bit不一样。然后考虑到A和B一个bit不一样,A和C一个bit不一样,A,B,C各不相同,那么B和C一定不会只有一个bit不一样,所以若是两个数只有一个bit不一样,我们就在它们之间连一条边,可以发现这个图是个二分图。答案就是这个二分图的最大点独立集。
#include<bits/stdc++.h>
#define N 5050
using namespace std; typedef struct
{
int to,next;
long long flow;
bool is_match;
}ss; ss edg[*N];
int now_edge=,s,t;
int head[N]; void addedge(int u,int v)
{
edg[now_edge]=(ss){v,head[u],};
head[u]=now_edge++;
} void addedge(int u,int v,long long flow)
{
// printf("%d %d\n",u,v); edg[now_edge]=(ss){v,head[u],flow};
head[u]=now_edge++; edg[now_edge]=(ss){u,head[v],};
head[v]=now_edge++;
} int dis[N]; bool bfs()
{
memset(dis,,sizeof(dis));
queue<int>q;
q.push(s);
dis[s]=; while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now];i!=-;i=edg[i].next)
{
ss &e=edg[i];
if(e.flow>&&dis[e.to]==)
{
dis[e.to]=dis[now]+;
q.push(e.to);
}
}
} if(dis[t]==)return ;
return ;
} int current[N];
long long dfs(int x,long long maxflow)
{
if(x==t)return maxflow;
for(int i=current[x];i!=-;i=edg[i].next)
{
current[x]=i;
ss &e=edg[i];
if(e.flow>&&dis[e.to]==dis[x]+)
{
long long flow=dfs(e.to,min(maxflow,e.flow));
if(flow!=)
{
e.flow-=flow;
edg[i^].flow+=flow;
return flow;
}
}
}
return ;
} long long dinic()//最大流
{
long long ans=,flow;
while(bfs())
{
for(int i=;i<N;i++)current[i]=head[i];
while(flow=dfs(s,LLONG_MAX/))ans+=flow;
}
return ans;
} void init()
{
for(int i=;i<N;i++)head[i]=-;
now_edge=;
} int arr[N];
int color[N]={}; void Bipartite_graph_coloring(int x,int now_color)//二分图染色
{
if(color[x])return;
color[x]=now_color;
for(int i=head[x];i!=-;i=edg[i].next)Bipartite_graph_coloring(edg[i].to,now_color*-);
} bool is_match_vertex[N]={};
int is_ans[N]={};
void dfs(int x,int type)//寻找最小点覆盖集中的点,不在该集合中的点就是最大点独立集的点
{
if(is_ans[x])return;
is_ans[x]=;
for(int i=head[x];i!=-;i=edg[i].next)
{
int v=edg[i].to;
if(v==s||v==t)continue; if(edg[i].is_match==(bool)type)dfs(v,-type);
}
} int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&arr[i]); init();
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
int now=arr[i]^arr[j];
if(now==(now&-now))
{
addedge(i,j);
addedge(j,i);
// printf("%d %d\n",arr[i],arr[j]);
}
}
} for(int i=;i<=n;i++)
if(!color[i])Bipartite_graph_coloring(i,);//先将图划分成二分图 /* for(int i=1;i<=n;i++)if(color[i]==1)printf("%d ",arr[i]);
printf("\n");
for(int i=1;i<=n;i++)if(color[i]==-1)printf("%d ",arr[i]);
printf("\n");*/ init(); s=n+,t=s+;
for(int i=;i<=n;i++)
{
if(color[i]==)addedge(s,i,);
else
addedge(i,t,); if(color[i]==)
{
for(int j=;j<=n;j++)
{
int now=arr[i]^arr[j];
if(now==(now&-now))
{
addedge(i,j,);//建边准备跑二分图匹配
}
}
}
}
int ans=n-dinic();
printf("%d\n",ans); for(int i=;i<=n;i++)
{
if(color[i]==)
{
for(int j=head[i];j!=-;j=edg[j].next)
{
if(edg[j].to!=s&&edg[j^].flow)
{
edg[j].is_match=edg[j^].is_match=true;
is_match_vertex[i]=is_match_vertex[edg[j].to]=true;
}
else
{
edg[j].is_match=edg[j^].is_match=false;
}
}
}
} for(int i=;i<=n;i++)
{
if(color[i]==-&&is_match_vertex[i]==false)
{
dfs(i,);
}
} for(int i=;i<=n;i++)
{
if(color[i]==&&!is_ans[i]||color[i]==-&&is_ans[i])printf("%d%c",arr[i],--ans== ? '\n': ' ');
}
return ;
}
 
 

最新文章

  1. angular中ng-repeat ng-if 中的变量的值控制器中为什么取不到
  2. 使用elasticsearch的关键技术点
  3. UVA 1626 Brackets sequence(括号匹配 + 区间DP)
  4. eclipse 发布APK
  5. 【转】如何使用PhoneGap打包Web App
  6. iOS使用AVFoundation实现二维码扫描
  7. 微软职位内部推荐-Senior Software Development Engineer
  8. (3)java棧
  9. 移动app的一些心得
  10. ubuntu16编译安装mysql5.7
  11. webView调用系统地图,电话,和跳转链接的方法
  12. 阿里云linux下web服务器配置
  13. [Flask]学习杂记一 Hello程序
  14. python矩阵的切片(或截取)
  15. MySQL系列详解八:MySQL多线程复制演示-技术流ken
  16. xshell的Solarized Dark配色方案
  17. pow 的使用和常见问题
  18. jquery 不选择第一个
  19. debian 7 终端上无法调出输出法
  20. Sublime Text 3中文乱码问题解决

热门文章

  1. Java性能优化的50个细节,我必须分享给你!
  2. 6_3.springboot2.x数据整合Mybatis(注解和非注解)
  3. 11_springmvc之RESTful支持
  4. POJ 1873 /// 状压+凸包
  5. Activiti添加批注(comment)信息
  6. Android开发 BottomNavigationView学习
  7. Error:(27, 13) Failed to resolve: com.android.support.constraint:constraint-layout:1.0.2约束布局constraint-layout导入失败的解决方案
  8. leetcode146周赛-5130-等价多米诺骨牌对的数量
  9. [JZOJ3171] 【GDOI2013模拟4】重心
  10. 2016.8.18上午纪中初中部NOIP普及组比赛