分析:
首先有一个小技巧,是本题的关键:
任意一条 1 1 到的路径的异或和,都可以由任意一条 1 1 到路径的异或和与图中的一些环的异或和来组合得到
这个怎么理解呢 ?
我们可以找到一条主干线
而路上有环都可以归结成一下情况:
权值就是一条单路径(1->n)+所有环
一遍dfs把ta们求出来就可以了
复杂度O(n+m)
求出线性基,里面存储的就是各个环的xor值
因为我们用高斯消元把线性基消成了上三角形,所以在统计答案的时候
需要判断一下: if (b[j]&&((ans^b[j])>ans))
、
tip
注意a数组的大小
因为dis是ll类型的,以后判断该位上是否是一的时候都这么写:a[i]>>j&1
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=50005;
struct node{
int y,nxt;
ll v;
};
node way[N<<2];
int st[N],tot=0,n,m,cnt=0;
ll a[N*20],b[100],dis[N];
bool vis[N];
void add(int u,int w,ll z) {
tot++;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot;
tot++;way[tot].y=u;way[tot].v=z;way[tot].nxt=st[w];st[w]=tot;
}
void dfs(int now) {
vis[now]=1;
for (int i=st[now];i;i=way[i].nxt)
if (vis[way[i].y]) { //环
a[++cnt]=dis[now]^dis[way[i].y]^way[i].v;
} else {
dis[way[i].y]=dis[now]^way[i].v;
dfs(way[i].y);
}
}
void cal() {
ll ans=dis[n]; //主干线
for (int i=1;i<=cnt;i++)
for (int j=63;j>=0;j--)
if (a[i]>>j&1) {
if (b[j]) a[i]^=b[j];
else {
b[j]=a[i];
break;
}
}
for (int j=63;j>=0;j--)
if (b[j]&&((ans^b[j])>ans))
ans^=b[j];
printf("%lld",ans);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++) {
int u,w;ll z;
scanf("%d%d%lld",&u,&w,&z);
add(u,w,z);
}
dfs(1);
cal();
return 0;
}