BZOJ 3943 [Usaco2015 Feb]SuperBull:最大生成树

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3943

题意:

  有n只队伍,每个队伍有一个编号a[i]。

  每场比赛有两支队伍参加,然后选一支队伍淘汰。共进行n-1场比赛,然后比赛结束。

  若某场比赛是队伍i和j参加,则该场比赛的得分为a[i] xor a[j]。

  问最大的总得分。

 

题解:

  每两支队伍(i,j)连一条边,边权为a[i] xor a[j]。

  然后求最大生成树即可。

 

AC Code:

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <algorithm>
  5 #include <vector>
  6 #define MAX_N 2005
  7 
  8 using namespace std;
  9 
 10 struct Edge
 11 {
 12     int sour;
 13     int dest;
 14     long long len;
 15     Edge(int _sour,int _dest,long long _len)
 16     {
 17         sour=_sour;
 18         dest=_dest;
 19         len=_len;
 20     }
 21     Edge(){}
 22     friend bool operator < (const Edge &a,const Edge &b)
 23     {
 24         return a.len>b.len;
 25     }
 26 };
 27 
 28 int n;
 29 int par[MAX_N];
 30 long long ans;
 31 long long a[MAX_N];
 32 vector<Edge> edge;
 33 
 34 void read()
 35 {
 36     cin>>n;
 37     for(int i=0;i<n;i++)
 38     {
 39         cin>>a[i];
 40     }
 41 }
 42 
 43 void build_graph()
 44 {
 45     for(int i=0;i<n;i++)
 46     {
 47         for(int j=0;j<i;j++)
 48         {
 49             edge.push_back(Edge(i,j,a[i]^a[j]));
 50         }
 51     }
 52 }
 53 
 54 void init_union_find()
 55 {
 56     for(int i=0;i<n;i++)
 57     {
 58         par[i]=i;
 59     }
 60 }
 61 
 62 int find(int x)
 63 {
 64     return par[x]==x?x:par[x]=find(par[x]);
 65 }
 66 
 67 void unite(int x,int y)
 68 {
 69     int px=find(x);
 70     int py=find(y);
 71     if(px==py) return;
 72     par[px]=py;
 73 }
 74 
 75 bool same(int x,int y)
 76 {
 77     return find(x)==find(y);
 78 }
 79 
 80 long long kruskal()
 81 {
 82     init_union_find();
 83     sort(edge.begin(),edge.end());
 84     int cnt=0;
 85     long long res=0;
 86     for(int i=0;i<edge.size();i++)
 87     {
 88         Edge temp=edge[i];
 89         if(!same(temp.sour,temp.dest))
 90         {
 91             cnt++;
 92             res+=temp.len;
 93             unite(temp.sour,temp.dest);
 94         }
 95     }
 96     return cnt==n-1?res:-1;
 97 }
 98 
 99 void solve()
100 {
101     build_graph();
102     ans=kruskal();
103 }
104 
105 void print()
106 {
107     cout<<ans<<endl;
108 }
109 
110 int main()
111 {
112     read();
113     solve();
114     print();
115 }

 

posted @ 2017-10-16 19:02  Leohh  阅读(201)  评论(0编辑  收藏  举报