八中足球赛
Description
八中在办一次足球锦标赛,有N个队伍参加,每个队的编号为1到N中某个值。
每个队有个特征值为1-2^30-1之间的整数,且各不相同
比赛在决出冠军后就结束了
小Z发现每次比赛的兴奋值为两个队特征值的异或值(异或可理解为不进位的二进制加法运算)
例如特征值为2与特征值为4的队伍比赛,兴奋值为6.
这样小Z为了使整个赛事兴奋值总和最大,开启天眼模式,即他可以决定每场比赛的胜利者是哪个队。
现在给出每个队的特征值,求兴奋值的最大是多少
Input
第一行包含一个整数N
接下来的N行包含N个整数,第i个整数代表第i支队伍的特征值,
1<=N<=2000
Output
所有比赛兴奋值总和的最大值
Sample Input
3
1
2
3
Sample Output
5
//先让1和2打,兴奋为3,然后让1胜出,再让1与3打,兴奋值为2.总和为5
每一场比赛可以淘汰一支队伍,所以n支队伍需要(n-1)次比赛。求最大生成树就可得出ans。
注意队伍编号的范围,开long long。
#include<bits/stdc++.h>
using namespace std;
int n,tot=0,f[2010],sum=0,ix,iy,fx,fy;
long long num[2010],ans=0;
struct note
{
int x,y;
long long v;
}d[2001010];
bool cmp(note a,note b)
{
return a.v>b.v;
}
int find(int x)
{
if(f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
void put(int a,int b,long long c)
{
tot++;
d[tot].x=a;
d[tot].y=b;
d[tot].v=c;
}
void mst()
{
for(int i=1;i<=tot;i++)
{
ix=d[i].x;
iy=d[i].y;
fx=find(ix);
fy=find(iy);
if(fx!=fy)
{
f[fx]=fy;
ans=ans+d[i].v;
sum++;
if(sum+1==n)
return ;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&num[i]);
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
put(i,j,num[i] xor num[j]);
for(int i=1;i<=2005;i++)
f[i]=i;
sort(d+1,d+tot+1,cmp);
mst();
printf("%lld",ans);
}