Connecting...

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相切
*/

参考 良心blog

posted @ 2024-07-21 21:26  余亦宸  阅读(22)  评论(0)    收藏  举报