第二道线形基啊,开心
开题的时候以为要用tarjan缩一遍图,然后在新图上,跑出一条简单路径,再把每个新点扔进线形基,就可以了
码了80行忽然发现好像这样没法做,赶紧去上了个厕所冷静了一下,然后发现直接dfs就好了
废话一堆
首先,dfs整个图,用dis[]记录每个点的距离,vis[]记录是否到达过,若到达过证明是个环,扔进线形基里面就好了
最后查询输出即可
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=2e5+7; int m,n,k,cnt,head[N]; ll dis[N]; struct xxj { ll p[60]; void insert(ll x) { for (int i=60;i>=0;i--) if (x&(1ll<<i)) { if (!p[i]) {p[i]=x;break;} else x^=p[i]; } } ll query(ll x) { for (int i=60;i>=0;i--) x=max(x,x^p[i]); return x; } } G; struct edge { int nx,to; ll dist; } e[N]; void add_edge(int a,int b,ll dist) { cnt++;e[cnt].to=b;e[cnt].nx=head[a];e[cnt].dist=dist;head[a]=cnt; cnt++;e[cnt].to=a;e[cnt].nx=head[b];e[cnt].dist=dist;head[b]=cnt; } bool vis[N]; void dfs(int x) { vis[x]=true; for (int i=head[x];i;i=e[i].nx) { int y=e[i].to; if (!vis[y]) dis[y]=dis[x]^e[i].dist,dfs(y); else G.insert(dis[x]^dis[y]^e[i].dist); } } int main() { freopen("xorr.in","r",stdin); freopen("xorr.out","w",stdout); scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int x,y; ll z; scanf("%d%d%lld",&x,&y,&z); add_edge(x,y,z); } dfs(1); printf("%lld ",G.query(dis[n])); return 0; }