BZOJ2115: [Wc2011] Xor(洛谷P4151)
阿新 • • 發佈:2018-12-17
線性基
妙蛙
假如我們已經找到一條路徑,如果要使答案變大,顯然只能在這條路徑上加環。而從路徑到環的邊會走兩遍,因此不會影響答案。那麼我們把所有環扔進線性基裡,然後用這條路徑求出最大值即可。
至於這條路徑,其實是可以隨便選的。因為如果另一條路徑比它更優,它們就會形成環,線上性基裡就會變成另一條路徑了。
程式碼:
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 50005
#define F inline
using namespace std;
typedef long long LL;
struct edge{ int nxt,to; LL d; }ed[N<<2];
int n,m,k,h[N]; LL s[N],p[64]; bool f[N];
F char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
return l==r?EOF:*l++;
}
F LL _read(){
LL x=0; char ch=readc();
while (!isdigit(ch)) ch=readc ();
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
return x;
}
#define add(x,y,z) ed[++k]=(edge){h[x],y,z},h[x]=k
F void nsrt(LL x){
for (int i=63;~i;i--)
if ((x>>i)&1) if (!p[i]){ p[i]=x; break; } else x^=p[i];
}
F LL srch(LL x){ for (int i=63;~i;i--) if ((x^p[i] )>x) x^=p[i]; return x; }
void dfs(int x,LL sum){
s[x]=sum,f[x]=true;
for (int i=h[x],v;i;i=ed[i].nxt)
if (!f[v=ed[i].to]) dfs(v,sum^ed[i].d);
else nsrt(sum^ed[i].d^s[v]);
}
int main(){
n=_read(),m=_read();
for (int i=1;i<=m;i++){
int x=_read(),y=_read(); LL z=_read();
add(x,y,z),add(y,x,z);
}
return dfs(1,0),printf("%lld\n",srch(s[n])),0;
}