D132 最小生成树 Kruskal 算法 P4826 [USACO15FEB] Superbull S

D132 最小生成树 Kruskal 算法 P4826 [USACO15FEB] Superbull S_哔哩哔哩_bilibili

 

P4826 [USACO15FEB] Superbull S - 洛谷

淘汰赛,求点权异或和的最大值。

思路

先把任意两点的点权异或值转化到边上

逐个淘汰点,贪心思考,先选大边权,也就是跑最大生成树,求边权和

相关板子:

D08【模板】最小生成树 Kruskal 算法 - 董晓 - 博客园

 

// 最大生成树 Kruskal算法 O(MlogM)
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=2010,M=4000010;
int n,m,tot,ans,a[N],fa[N];
pair<int,pair<int,int> >e[M]; //边集

int find(int u){ //并查集的找根
  return fa[u]==u?u:fa[u]=find(fa[u]);
}
void kruskal(){
  sort(e+1,e+m+1); //排序
  reverse(e+1,e+m+1); //逆序
  for(int i=1; i<=n; i++) fa[i]=i;
  for(int i=1; i<=m; i++){
    int x=find(e[i].second.first),y=find(e[i].second.second);
    if(x!=y){
      fa[x]=y;
      ans+=e[i].first;
      if(++tot==n-1) break;
    }
  }
  cout<<ans;
}
signed main(){
  cin>>n;
  for(int i=1,x;i<=n;i++)cin>>a[i];
  for(int i=1;i<=n;i++)
    for(int j=1;j<i;j++)
      e[++m]={a[i]^a[j],{i,j}};

  kruskal();
}

 

posted @ 2026-04-14 22:08  董晓  阅读(66)  评论(0)    收藏  举报