【题目分析】
显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可。
但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有的简单环都可以经过各种各样的异或得到。
然后线性基,在从高位向低位贪心即可,至于证明,需要拟阵的相关知识。
【代码】
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define maxn 100005
#define ll long long
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int h[maxn],to[maxn<<1],ne[maxn<<1];
ll w[maxn<<1];
int en=0,n,m,vis[maxn],tot=0;
ll a[maxn<<1];
ll dis[maxn];
void add(int a,int b,ll c)
{
to[en]=b;
w[en]=c;
ne[en]=h[a];
h[a]=en++;
}
void dfs(int k)
{
// printf("dfs on %d\n",k);
vis[k]=1;
for (int i=h[k];i>=0;i=ne[i])
{
if (!vis[to[i]])
{
dis[to[i]]=dis[k]^w[i];
dfs(to[i]);
}
else a[++tot]=dis[k]^dis[to[i]]^w[i];
}
}
ll lb[64],ans;
int main()
{
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
for (int i=1;i<=m;++i)
{
int a,b; ll c;
scanf("%d%d%lld",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
dfs(1);
ans=dis[n];
// for (int i=1;i<=n;++i) cout<<dis[i]<<" "; cout<<endl;
// for (int i=1;i<=tot;++i) cout<<a[i]<<" ";cout<<endl;
for (int i=1;i<=tot;++i)
{
for (int j=63;j>=0;j--)
{
if ((a[i]>>j)&1){
if (!lb[j]) {lb[j]=a[i];break;}
else a[i]^=lb[j];
}
}
}
for (int i=63;i>=0;i--)
if (lb[i]&&((ans>>i)&1)==0) ans^=lb[i];
cout<<ans<<endl;
return 0;
}