第一行包含两个整数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
Sample Output
6
1到n点的异或和即为1到n的任意一条线异或上路径上若干的环,所以dfs出所有环放入线性基顺便得到一条路,再用这条路遍历线性基找到最大异或值
#include<bits/stdc++.h>
#define ll long long
#define MAXN 50005
using namespace std;
struct node
{
int to;
ll val;
};
vector<node> edge[MAXN];
ll dis[MAXN];
int vis[MAXN];
struct L_B
{
ll b[65],p[65];
int cnt,flag;
L_B()
{
memset(p,0,sizeof(p));
memset(b,0,sizeof(b));
cnt = flag = 0;
}
inline bool insert(ll x)
{
for(int i = 62;i >= 0;--i)
if(x & (1ll <<i))
{
if(b[i])
x ^= b[i];
else
{
b[i] = x;
return true;
}
}
flag = 1;
return false;
}
ll get_max(ll ret)
{
for(int i = 62;i >= 0;--i)
if((ret^b[i]) > ret)
ret ^= b[i];
return ret;
}
ll get_min()
{
if(flag)
return 0;
for(int i = 0;i <= 62;++i)
if(b[i])
return b[i];
return 0;
}
inline void rebuild()
{
for(int i = 62;i >= 1;--i)
if(b[i])
for(int j = i-1;j >= 0;--j)
if(b[i] & (1ll << j))
b[i] ^= b[j];
for(int i = 0;i <= 62;++i)
if(b[i])
p[cnt++] = b[i];
}
ll kth(ll k)
{
if(flag)
--k;
if(k == 0)
return 0;
ll ret = 0;
if(k >= (1ll << cnt))
return -1;
for(int i = 0;i <= cnt-1;++i)
if(k & (1ll << i))
ret ^= p[i];
return ret;
}
};
L_B lis;
void dfs(int u,int v)
{
vis[u]=1;
for(int i=0;i<edge[u].size();i++)
{
if(edge[u][i].to==v)
continue;
if(!vis[edge[u][i].to])
dis[edge[u][i].to]=dis[u]^edge[u][i].val,dfs(edge[u][i].to,u);
else
lis.insert(dis[edge[u][i].to]^edge[u][i].val^dis[u]);
}
}
int main()
{
int n,m;
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
while(m--)
{
int u,v;
ll val;
scanf("%d%d%lld",&u,&v,&val);
node temp;
temp.to=v;
temp.val=val;
edge[u].push_back(temp);
temp.to=u;
edge[v].push_back(temp);
}
dfs(1,0);
printf("%lld\n",lis.get_max(dis[n]));
}