[bzoj2115]Xor
任选一条路径,考虑如果从一个点向另外一个方向走,该方向上一定有一个环(否则来去无意义),所以相当于一条路径+许多的环异或最大值,可以用线性基来求
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define ll long long 5 struct ji{ 6 int nex,to; 7 ll len; 8 }edge[N<<2]; 9 int E,n,m,x,y,head[N],vis[N]; 10 ll z,a[61],s[N]; 11 void add(int x,int y,ll z){ 12 edge[E].nex=head[x]; 13 edge[E].to=y; 14 edge[E].len=z; 15 head[x]=E++; 16 } 17 void add(ll k){ 18 for(int i=60;i>=0;i--) 19 if (k&(1LL<<i)) 20 if (a[i])k^=a[i]; 21 else{ 22 a[i]=k; 23 break; 24 } 25 } 26 void dfs(int k,int fa,ll sh){ 27 s[k]=sh; 28 vis[k]=1; 29 for(int i=head[k];i!=-1;i=edge[i].nex) 30 if (i!=fa) 31 if (!vis[edge[i].to])dfs(edge[i].to,i^1,s[k]^edge[i].len); 32 else add(s[k]^s[edge[i].to]^edge[i].len); 33 } 34 ll query(ll k){ 35 for(int j=60;j>=0;j--) 36 if ((k&(1LL<<j))==0)k^=a[j]; 37 return k; 38 } 39 int main(){ 40 scanf("%d%d",&n,&m); 41 memset(head,-1,sizeof(head)); 42 for(int i=1;i<=m;i++){ 43 scanf("%d%d%lld",&x,&y,&z); 44 add(x,y,z); 45 add(y,x,z); 46 } 47 dfs(1,-1,0); 48 printf("%lld",query(s[n])); 49 }