题目链接
思路
找到一条到终点的异或值
- 对于所有环,总是可以从终点跑到环再跑回终点(环跑一次,连线跑了两次),所以所有环的权值都可以直接异或。
- 对于一条其他路线从起点到终点,说明原路径存在环,换一条路即异或环。
所以预设一条路为初值,并找到所有的环求线性基。
最后求个异或最大值即可
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
vector<pair<ll,ll> > e[50005];
ll vis[50005], w[50005], ans, n, p[100];
void ins(ll num)
{
for(ll i = 63; ~i; --i)
{
if((num>>i)&1)
{
if(p[i]) num ^= p[i];
else
{
p[i] = num;
break;
}
}
}
}
void dfs(ll u)
{
for(ll i = e[u].size()-1; ~i; --i)
{
ll v = e[u][i].first;
ll tmp = e[u][i].second;
if(vis[v]) ins(w[u]^w[v]^tmp);
else
{
vis[v] = 1;
w[v] = w[u]^tmp;
if(v == n) ans = w[v];
dfs(v);
}
}
}
int main()
{
ll m, u, v, w;
scanf("%lld%lld",&n,&m);
for(ll i = 1; i <= m ; ++i)
{
scanf("%lld%lld%lld",&u,&v,&w);
e[u].push_back({v,w});
e[v].push_back({u,w});
}
vis[1] = 1;
dfs(1);
for(ll i = 63; ~i; --i) if(p[i] && ((ans>>i)&1) == 0) ans ^= p[i];
printf("%lld\n",ans);
return 0;
}