本题关键是抓住xor的性质:a^b^a=b
异或两次等于0
1到N,一定是走一条路,可能再往别处走出环
每个环都可以“独立”走出来
1到N的路径,可以拆成任意一条路和若干个环拼成的
dfs找环,加入线性基
随便找一条路,在线性基中查询
能变大就异或上去。
O(M*64)
#include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=50000+5; const int M=100000+5; struct node{ int nxt,to; ll val; }e[2*M]; int hd[N],cnt=1; int n,m; void add(int x,int y,ll z){ e[++cnt].nxt=hd[x]; e[cnt].to=y; e[cnt].val=z; hd[x]=cnt; } struct linebase{ ll a[70]; void ins(ll x){ for(reg i=61;i>=0;--i){ if(x&((ll)1<<i)){ if(!a[i]){ a[i]=x;return; } else{ x^=a[i]; } } } return; } ll query(ll x){ ll ret=x; for(reg i=61;i>=0;--i){ if(a[i]){ if((ret^a[i])>ret) ret^=a[i]; } } return ret; } }lb; ll f[N]; bool vis[N]; void dfs(int x,int in_edge){ vis[x]=1; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(i==(in_edge^1)) continue; if(!vis[y]){ f[y]=f[x]^e[i].val; dfs(y,i); }else{ ll tmp=f[x]^f[y]^e[i].val; lb.ins(tmp); } } } int main(){ rd(n);rd(m); int x,y; ll z; for(reg i=1;i<=m;++i){ rd(x);rd(y);scanf("%lld",&z); add(x,y,z);add(y,x,z); } dfs(1,0); printf("%lld ",lb.query(f[n])); return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2019/1/1 16:08:00 */