题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6614
给你n个点,让你构造一棵最小生成树,边权是两个点的编号按位与的结果 让你输出最小生成树的最小值 和边
思路:由于是按位与,每个节点化成2进制从右边开始找到第一个二进制位零的位置x,然后这个点连接(1<<x)点 如果没有0 比如7(111)那就让它+1 判断是不是在n之内就好了
#include <iostream>
#include <cstdio>
#define ll long long
const int maxn = 2e5+5;
using namespace std;
int ans[maxn];
int main()
{
int T,n,sum=0;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
sum = 0;
for(int i = n; i >= 2; i--) {
int tt = i;
int cnt = 0;
int flag = 0;
while(tt){
if(tt % 2 == 0) {
ans[i] = (1 << cnt);
flag = 1;
break;
}
tt /= 2;
cnt++;
}
if(flag == 0) {
if(i + 1 <= n){
ans[i] = i + 1;
}
else {
sum++;
ans[i] = 1;
}
}
}
printf("%d\n",sum);
for(int i=2;i<n;i++) {
printf("%d ",ans[i]);
}
printf("%d\n",ans[n]);
}
return 0;
}