bzoj2115 xor
这个题网上题解挺多的,讲的也挺详细的,所以我就不必过多赘述。大体思路就是任意选一条1-n的路径,和一些独立环xor起来得到一个最大值就是答案。
注意个和路径不相交的环,那么它们xor起来的结果的意义就是从路径上任意一点走到环,遍历一遍再从原路返回路径,路径连接环的那段被走了两次,xor值抵消。
注意独立环的个数有m-n+1个,求得时候dfs,每条dfs树的非树边对应一个环。
xor
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #define maxn 200000 7 #define bit 64 8 #define inf 1000000000 9 using namespace std; 10 typedef unsigned long long LL; 11 LL a[maxn],d[maxn]; 12 int fir[maxn]; 13 bool v[maxn]; 14 int n,m,tot,num,cnt; 15 struct et 16 { 17 int s,t,next; 18 LL val; 19 void add(int x,int y,LL z) 20 { 21 s=x; t=y; val=z; next=fir[x]; fir[x]=tot; 22 } 23 }e[maxn*2]; 24 25 void dfs(int x) 26 { 27 v[x]=1; 28 for (int j=fir[x];j;j=e[j].next) 29 { 30 int k=e[j].t; 31 if (!v[k]) d[k]=d[x]^e[j].val,dfs(k); 32 else a[++num]=d[k]^e[j].val^d[x]; 33 } 34 } 35 36 int gauss(int n) 37 { 38 int k=1; 39 for (int i=bit;i;i--) 40 { 41 int p=0; 42 for (int j=k;j<=n;j++) if ((a[j]>>(i-1))&1) { p=j; break; } 43 if (p) 44 { 45 swap(a[k],a[p]); 46 for (int j=1;j<=n;j++) if ((j!=k)&&((a[j]>>(i-1))&1)) a[j]^=a[k]; 47 k++; 48 } 49 } 50 return k-1; 51 } 52 53 int main() 54 { 55 freopen("xor.in","r",stdin); 56 scanf("%d%d",&n,&m); 57 int x,y; LL z; 58 for (int i=1;i<=m;i++) 59 { 60 scanf("%d%d%llu",&x,&y,&z); 61 e[++tot].add(x,y,z); 62 e[++tot].add(y,x,z); 63 } 64 dfs(1); 65 cnt=gauss(num); 66 LL ans=d[n]; 67 //cout<<ans<<endl; 68 for (int i=1;i<=cnt;i++) 69 if ((ans^a[i])>ans) ans^=a[i]; 70 printf("%llu\n",ans); 71 return 0; 72 }
AC without art, no better than WA !