bzoj 2115: [Wc2011] Xor 线性基+dfs树
2017-10-24 08:20
381 查看
题意
给出一个带权无向图,求一条1到n的路径使得其路径上边权的异或和最大。n<=50000,m<=100000
分析
把dfs树建出来后,所有边要么是树边要么是非树边。显然我们可以通过走一条反祖边来使我们的答案异或上该返祖边所在环的权值。那么就把所有环的权值扔到线性基里面,最后取个最大的即可。代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int N=50005; int cnt,n,m,last ; bool vis ; LL bas[65],bin[65],dis ; struct edge{int to,next;LL w;}e[N*4]; void addedge(int u,int v,LL w) { e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt; e[++cnt].to=u;e[cnt].w=w;e[cnt].next=last[v];last[v]=cnt; } void ins(LL x) { for (int i=60;i>=0;i--) if (x&bin[i]) { if (!bas[i]){bas[i]=x;break;} x^=bas[i]; } } void dfs(int x,int fa) { vis[x]=1; for (int i=last[x];i;i=e[i].next) if (!vis[e[i].to]) dis[e[i].to]=dis[x]^e[i].w,dfs(e[i].to,i); else if (i!=(fa^1)) ins(dis[x]^dis[e[i].to]^e[i].w); } int main() { bin[0]=1; for (int i=1;i<=60;i++) bin[i]=bin[i-1]*2; scanf("%d%d",&n,&m);cnt=1; for (int i=1;i<=m;i++) { int x,y;LL z; scanf("%d%d%lld",&x,&y,&z); addedge(x,y,z); } dfs(1,0); LL ans=dis ; for (int i=60;i>=0;i--) if ((ans^bas[i])>ans) ans^=bas[i]; printf("%lld",ans); return 0; }
相关文章推荐
- BZOJ 2115: [Wc2011] Xor DFS + 线性基
- BZOJ 2115 【WC2011】 Xor
- BZOJ-2115-Xor-WC2011
- bzoj 2115: [Wc2011] Xor(DFS+线性基)
- BZOJ 2115([Wc2011] Xor-线性基求法)
- bzoj 2115: [Wc2011] Xor【线性基+dfs】
- bzoj 2115: [Wc2011] Xor xor高斯消元
- 【BZOJ 2115】[Wc2011] Xor 线性基
- Bzoj 2115: [Wc2011] Xor
- bzoj 2115: [Wc2011] Xor
- BZOJ 2115 [Wc2011] Xor
- BZOJ 2115: [Wc2011] Xor
- BZOJ 2115: [Wc2011] Xor [高斯消元XOR 线性基 图]
- bzoj 2115: [Wc2011] Xor
- BZOJ 2115 [Wc2011] Xor 高斯消元
- BZOJ 2115: [Wc2011] Xor (dfs + gauss 线性基 异或最长路)
- bzoj 2115 [Wc2011] Xor
- 【BZOJ 2115】 [Wc2011] Xor
- 【BZOJ】2115: [Wc2011] Xor
- BZOJ 2115: [Wc2011] Xor