G67 线性基+贪心法 P4151 [WC2011] 最大XOR和路径
视频链接:G67 线性基+贪心法 P4151 [WC2011] 最大XOR和路径_哔哩哔哩_bilibili
P4151 [WC2011] 最大XOR和路径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
// 线性基+贪心法 O(63*M) #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define LL long long const LL N=100005; LL n,m,idx; LL head[N]; struct E{ LL to,ne,w; }e[N<<1]; LL sum[N],vis[N],p[64]; void add(LL a,LL b,LL c){ e[++idx].to=b;e[idx].w=c;e[idx].ne=head[a]; head[a]=idx; } void insert(LL x){ for(int i=63;i>=0;--i){ if(x>>i&1){ //x第i位为1 if(!p[i]){ //不存在则加入 p[i]=x; break; } x^=p[i]; //存在则异或 } } } void dfs(LL x){ vis[x]=1; for(int i=head[x];i;i=e[i].ne){ LL y=e[i].to; // 没有搜过y,则继续搜索 // 否则 把环的异或和插入线性基 if(!vis[y]) sum[y]=sum[x]^e[i].w, dfs(y); else insert(sum[x]^e[i].w^sum[y]); } } int main(){ scanf("%lld%lld",&n,&m); for(int i=1;i<=m;++i){ LL a,b,c; scanf("%lld%lld%lld",&a,&b,&c); add(a,b,c); add(b,a,c); } dfs(1); LL ans=sum[n]; //1到n的链的异或和 for(int i=63;i>=0;--i)ans=max(ans,ans^p[i]); printf("%lld\n",ans); }