EZOJ #202

传送门

分析

我们知道选一个点的代价就是他所有出边边权的异或和

由于一条边如果两个端点均选边权会异或两次变回0,所以不必担心重复的情况

于是直接跑线性基即可

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node {
    int sum,val;
};
node d[100100];
int belong [110];
inline bool cmp(const node x,const node y){return x.val>y.val;}
signed main(){
    int n,m,i,j,k,Ans=0;
    scanf("%lld%lld",&n,&m);
    for(i=1;i<=n;i++)scanf("%lld",&d[i].val),Ans-=d[i].val;
    for(i=1;i<=m;i++){
      int x,y,z;
      scanf("%lld%lld%lld",&x,&y,&z);
      d[x].sum^=z;
      d[y].sum^=z;
    }
    sort(d+1,d+n+1,cmp);
    for(i=1;i<=n;i++){
      k=d[i].sum;
      for(j=62;j>=0;j--)
        if((1ll<<j)&k){
          if(!belong[j]){
              belong[j]=k;
              Ans+=2*d[i].val;
              break;
          }
          k^=belong[j];
        }
    }
    cout<<Ans;
    return 0;
}
posted @ 2019-02-28 22:39  水题收割者  阅读(109)  评论(0编辑  收藏  举报