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;
}