1. 程式人生 > >巴卡爾

巴卡爾

順序 ons 自己的 等於 pri font max 容易 long

【題目背景】

“爆龍王”巴卡爾是群龍之王,剛進入魔界時,他曾憑強大而神秘的力量被任命為第九使徒。戰敗的巴卡爾利用寂靜城從魔界逃離到新的世界——天界。面對一個從未被魔界人發現的天界,巴卡爾為了削弱天族的反抗,利用自己的魔法部隊做前鋒,開始一步一步地對天界進行統治。

然而,恐怖如斯的巴卡爾在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 */

巴卡爾