【BZOJ2115】【WC2011】—Xor(线性基)

传送门

发现最后路径一定是一条路径加上很多个环
因为重复走的路径已经被消除了

就只需要把所有环找到求出线性基就可以了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int read(){
	char ch=getchar();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=getchar();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
	return f?res:-res;
}
inline ll readl(){
	char ch=getchar();
	ll res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=getchar();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
	return f?res:-res;
}
const int N=50005;
const int M=200005;
int adj[N],nxt[M],to[M],vis[N],tot,cnt;
ll p[65],val[M],cir[M],dis[N];
inline void addedge(int u,int v,ll k){
	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=k;
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa)continue;
		if(!vis[v])dis[v]=dis[u]^val[e],dfs(v,u);
		else cir[++tot]=dis[u]^dis[v]^val[e];
	}
}
signed main(){
	int n=read(),m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read();ll w=readl();
		addedge(u,v,w),addedge(v,u,w);
	}
	dfs(1,0);
	ll ans=dis[n];
	for(int i=1;i<=tot;i++){
		for(int j=60;~j;j--){
			if(!(cir[i]>>j))continue;
			if(p[j])cir[i]^=p[j];
			else {p[j]=cir[i];break;}
		}
	}
	for(int i=60;~i;i--)ans=max(ans,ans^p[i]);
	cout<<ans<<'\n';
}

posted @ 2019-04-09 21:58  Stargazer_cykoi  阅读(140)  评论(0编辑  收藏  举报