Shortest Path Problem? 解题报告
题目链接:Shortest Path Problem?
双倍经验(水两紫):P4151 [WC2011] 最大XOR和路径
思路:
线性基。看到XOR 路径 我还以为是矩阵乘法 ,除了XOR 最小应该没有啥指向LinearBasis了吧,在本题中,思路过于巧妙,线性鸡性质过于美妙。代码里有注释,且观之:
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+10;
int n,m;
int dis[maxn],vis[maxn];//dis[i] XOR distance of 1 ans i
struct Edge{
int v,w;
};
vector<Edge>g[maxn];
struct LinearBasis{
int a[66];
void insert(int x){
for(int i=62;i>=0;--i)if((x>>i)&1){
if(!a[i]){
a[i]=x;return;
}else x^=a[i];
}return ;
}
int query(int x){
for(int i=62;i>=0;--i)x=min(x,x^a[i]);
return x;
}
}L;
void dfs(int u,int fa){
vis[u]=1;
for(auto x:g[u])if(x.v!=fa){
int v=x.v,w=x.w;
if(!vis[v]){//树边
dis[v]=dis[u]^w;//先update
dfs(v,u);
}else {//非树边
L.insert(dis[u]^w^dis[v]);//出环 送入线性基
}
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>m;
int u,v,w;
for(int i=1;i<=m;++i){
cin>>u>>v>>w;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
dfs(1,-1);
// for(int i=1;i<=55;++i)cout<<L.a[i]<<" ";
cout<<L.query(dis[1]^dis[n]);
return 0;
}
/*
先任意造出一棵dfs树
1.对于任意树上路径,有唯一XOR和
2.对于G图上任意环,均可由树边和一条非树边构成
3.对于任意两点路径,均可由环和树边XOR出来(XOR两次相消)
把环加入线性基即可,任何环都可以与1相切
*/

浙公网安备 33010602011771号