https://www.lydsy.com/JudgeOnline/problem.php?id=2115
题意 : 给出一个连通无向图,求从1到n异或和最小的路径.
思路 :随意找一条简单路径 1-n 的,然后在这个过程中统计出 图中的环
然后 ,对这些环的异或值求一下 线性基,最后 贪心去异或取最值即可。
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 123456 ll n,m,head[maxn],cnt,w,u,v; ll ans,p[maxn],len,dis[maxn]; bool vis[maxn]; vector<ll>ok; struct node { ll v,w,to; } edge[maxn*2]; void add(ll u,ll v, ll w) { edge[++cnt].v=v; edge[cnt].w=w; edge[cnt].to=head[u]; head[u]=cnt; } void dfs(int u,ll sum) { vis[u]=1; dis[u]=sum; for(int i=head[u]; i!=-1; i=edge[i].to) { v=edge[i].v; w=edge[i].w; if(vis[v])ok.push_back(sum^dis[v]^w); else dfs(v,sum^w); } } void getj(ll x) { for(int i=60; i>=0; i--) { if(!(x>>i))continue; if(!p[i]) { p[i]=x; break; } else x^=p[i]; } } int main() { memset(head,-1,sizeof(head)); scanf("%lld%lld",&n,&m); while(m--) { scanf("%lld%lld%lld",&u,&v,&w); add(u,v,w); add(v,u,w); } dfs(1,0); len=ok.size(); for(int i=0; i<len; i++) getj(ok[i]); ans=dis[n]; for(int i=60; i>=0; i--) if((ans^p[i])>ans)ans^=p[i]; printf("%lld\n",ans); return 0; }