BZOJ2115: [Wc2011] Xor
$n \leq 5e4$,$m \leq 1e5$的边权无向图,问1到n的路径的边的异或和的最大值。
首先1到n的任意一条路径,可以由1到n的某一条路径异或上若干个环的异或和。
红色路径可以由黑色路径异或上两个环得到。
其次,我搞个树,然后一条非树边会和树边形成环,用这些只包含一条非树边的环异或起来可以得到所有的环。
哦它并不是要异或出所有的环而是要所有方案。两个环一起选也行。所以这样没问题。
然后丢进线性基找最大。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<time.h> 5 //#include<complex> 6 //#include<set> 7 //#include<queue> 8 #include<algorithm> 9 #include<stdlib.h> 10 using namespace std; 11 12 #define LL long long 13 int qread() 14 { 15 char c; int s=0; while ((c=getchar())<'0' || c>'9'); 16 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s; 17 } 18 19 //Pay attention to '-' , LL and double of qread!!!! 20 21 int n,m; 22 #define maxn 200011 23 struct Edge{int to,next; LL v;}edge[maxn<<1]; int first[maxn],le=2; 24 void in(int x,int y,LL v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;} 25 void insert(int x,int y,LL v) {in(x,y,v); in(y,x,v);} 26 27 struct JI 28 { 29 LL a[66]; int n; 30 void clear() {n=0; memset(a,0,sizeof(a));} 31 void insert(LL v) 32 { 33 for (int i=62;~i && v;i--) if ((v>>i)&1) 34 { 35 if (!a[i]) {a[i]=v; n++; break;} 36 v^=a[i]; 37 } 38 } 39 LL qmax() 40 { 41 LL ans=0; 42 for (int i=62;~i;i--) ((ans^a[i])>ans) && (ans^=a[i]); 43 return ans; 44 } 45 void rebuild() 46 { 47 for (int i=62;~i;i--) 48 for (int j=i-1;~j;j--) 49 if ((a[i]>>j)&1) a[i]^=a[j]; 50 } 51 LL p[66]; int lp; 52 LL query(LL K) 53 { 54 lp=0; for (int i=0;i<=62;i++) if (a[i]) p[lp++]=a[i]; 55 if (K>=(1ll<<lp)) return -1; 56 LL ans=0; 57 for (int i=lp-1;~i;i--) if ((K>>i)&1) ans^=p[i]; 58 return ans; 59 } 60 LL qmax(LL v) 61 { 62 LL ans=v; 63 for (int i=62;~i;i--) (((ans>>i)&1)==0 && (ans^=a[i])); 64 return ans; 65 } 66 }ji; 67 68 LL val[maxn]; 69 void dfs(int x,int fa) 70 { 71 for (int i=first[x];i;i=edge[i].next) 72 { 73 Edge &e=edge[i]; if (e.to==fa) continue; 74 if (!~val[e.to]) {val[e.to]=val[x]^e.v; dfs(e.to,x);} 75 else ji.insert(e.v^val[e.to]^val[x]); 76 } 77 } 78 79 int main() 80 { 81 n=qread(); m=qread(); 82 LL V; for (int i=1,x,y;i<=m;i++) {x=qread(); y=qread(); scanf("%lld",&V); insert(x,y,V);} 83 84 memset(val,-1,sizeof(val)); val[1]=0; 85 dfs(1,0); 86 printf("%lld\n",ji.qmax(val[n])); 87 return 0; 88 }