bzoj千题计划194:bzoj2115: [Wc2011] Xor
http://www.lydsy.com/JudgeOnline/problem.php?id=2115
边和点可以重复经过,那最后的路径一定是从1到n的一条路径加上许多环
dfs出任意一条路径的异或和、路径上所有环的异或和,加入线性基即可
#include<cstdio> #include<iostream> using namespace std; #define N 50001 #define M 100001 typedef long long LL; int n; int tot,front[N],to[M<<1],nxt[M<<1]; LL val[M<<1]; bool vis[N]; int cnt; LL dis[N]; LL a[M<<2]; LL b[61]; template<typename T> void read(T &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } void add(int u,int v,LL w) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w; } void dfs(int x,int y) { vis[x]=true; for(int i=front[x];i;i=nxt[i]) if(to[i]!=y) { if(!vis[to[i]]) dis[to[i]]=dis[x]^val[i],dfs(to[i],x); else a[++cnt]=dis[to[i]]^dis[x]^val[i]; } } void solve() { for(int i=1;i<=cnt;++i) for(int j=60;j>=0;--j) if(a[i]>>j&1) { if(!b[j]) { b[j]=a[i]; break; } a[i]^=b[j]; } LL ans=dis[n]; for(int i=60;i>=0;--i) if((ans^b[i])>ans) ans^=b[i]; cout<<ans; } int main() { int m; read(n); read(m); int u,v; LL w; while(m--) { read(u); read(v); read(w); add(u,v,w); } dfs(1,0); solve(); return 0; }
2115: [Wc2011] Xor
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 4064 Solved: 1691
[Submit][Status][Discuss]
Description
Input
第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。
Output
仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。
Sample Input
5 7
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2
Sample Output
6
HINT