码迷,mamicode.com
首页 > 其他好文 > 详细

巴卡尔

时间:2018-08-25 00:36:33      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:color   family   思路   clu   算法   namespace   noi   输入   algo   

【题目背景】

“爆龙王”巴卡尔是群龙之王,刚进入魔界时,他曾凭强大而神秘的力量被任命为第九使徒。战败的巴卡尔利用寂静城从魔界逃离到新的世界——天界。面对一个从未被魔界人发现的天界,巴卡尔为了削弱天族的反抗,利用自己的魔法部队做前锋,开始一步一步地对天界进行统治。

然而,恐怖如斯的巴卡尔在Justpenzi233一到天界的时候就抓住了他。

不巧,巴卡尔还特别喜欢……看足球。

【问题描述】

巴卡尔看的这场天界杯举办的尤其劣质,他希望你能解决这个问题。

一共有n支球队参加这场比赛,每支球队都有一个取值在 1~230-1 之间的整数编号。

足球锦标赛是一个淘汰赛制的比赛——每场比赛过后,你要选择一支球队淘汰,淘汰了的球队将不能再参加比赛。锦标赛在只有一支球队留下的时候就结束了。

巴卡尔告诉了你一个神奇的规律:在任意一场比赛中,这场比赛的得分是参加比赛两队的编号的异或(Xor)值。例如:12 编号为的队伍和编号为 20 的队伍之间的比赛的得分是 24 分,因为

技术分享图片

你需要安排一个比赛顺序,使得所有比赛的得分和最高。

【输入格式】

第一行一个正整数 n , 代表球队的数量。

接下来 n 行,第 i 行 1 个正整数,代表第 i 支球队的编号。

【输出格式】

一行一个非负整数,表示所有比赛得分之和的最大值。

【样例输入】

4

3

6

7

10

【样例输出】

34

【数据规模与约定】

对于30%的数据,n<=5

对于60%的数据,n<=100

对于100%的数据,n<=2000


 思路:

简单粗暴,容易发现这个题就是求个最大生成树,两点间的边权等于编号的异或值,用Kruskal或者Prim算法都能通过此题。

时间复杂度O(n log n)。

代码^-^

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MX=2001;
bool vis[MX];
long long a[MX],dis[MX],arr[MX][MX],n,cnt,ans;

void prime()
{
    memset(dis,-1,sizeof(dis));
    dis[1]=0;
    for(int i=1;i<=n;++i)
    {
        int pos=0;
        for(int j=1;j<=n;++j) 
            if(!vis[j] && dis[j]>=dis[pos]) pos=j;
        vis[pos]=1;ans+=dis[pos];
        for(int j=1;j<=n;++j) 
        {
            dis[j]=max(dis[j],arr[pos][j]);
        }
    }
}


int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;++i) 
        for(int j=1;j<=n;++j)
        if(i!=j)
            arr[i][j]=a[i]^a[j];
    
    prime();
    printf("%lld",ans);    
    return 0;
}
/* 
4 3 6 7 10
*/

 

 

 

巴卡尔

标签:color   family   思路   clu   算法   namespace   noi   输入   algo   

原文地址:https://www.cnblogs.com/qseer/p/9531609.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!