bzoj2115【WC2011】XOR
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=2115
sol :首先考虑处理出DFS树,那么树上的所有非树边可以构成一个简单环
因为所有不在1-n的路径上的树边都会被走过去再走回来,对答案无法构成影响
所以答案即为1-n路径的异或和^(所有环的异或和任选)的最大值
那么问题转化为从k个数中任选使其异或一个特定的数得异或和最大
直接跑线性基即可
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define int long long using namespace std; const int Mx=200010; int n,m,cnt,ans,now,tmp,val[Mx],cir[Mx],vis[Mx]; int tot,head[Mx],nxt[Mx],ver[Mx],cost[Mx]; void add(int x,int y,int z) { nxt[++tot]=head[x]; ver[tot]=y; cost[tot]=z; head[x]=tot; } void dfs(int x) { vis[x]=1; for(int i=head[x];i;i=nxt[i]) { int y=ver[i]; if(!vis[y]) val[y]=val[x]^cost[i],dfs(y); else cir[++cnt]=val[x]^val[y]^cost[i]; } } void gauss() { now=1,m=63; while(m--) { tmp=0; for(int j=now;j<=cnt;j++) if((cir[j]>>m)&1) { tmp=j;break; } if(tmp) { swap(cir[tmp],cir[now]); for(int j=1;j<=cnt;j++) if(j!=now&&((cir[j]>>m)&1)) cir[j]^=cir[now]; now++; } } } signed main() { scanf("%lld%lld",&n,&m); for(int i=1,x,y,z;i<=m;i++) { scanf("%lld%lld%lld",&x,&y,&z); add(x,y,z),add(y,x,z); } dfs(1); gauss(); ans=val[n]; for(int i=1;i<now;i++) ans=max(ans,ans^cir[i]); cout<<ans<<endl; return 0; }