• 洛谷 P4151 [WC2011]最大XOR和路径(线性基)


    传送门


    解题思路

    非常清新的一道题。

    先假设选择了一条1->n的主路径,然后在这条路径上向外拓展。

    发现只有环对答案有影响,因为非环的边一定会走两次,异或和为0。

    因为图是联通的,所以可以经过任意环,所以可以把所有的环的异或值扔到线性基里。

    然后再考虑选择哪一条路径,我们发现若1->n有多条路径,其实这些路径也构成了环,也会被加入到线性基里,这时候随便选一条路径即可。

    如何找环用的是题解中的方法,很巧妙。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<vector>
    using namespace std;
    const int maxn=50005;
    int cnt,p[maxn],vis[maxn],n,m;
    long long dis[maxn],a[maxn];
    struct node{
    	int v,next;
    	long long w;
    }e[maxn*4];
    void insert(int u,int v,long long w){
    	cnt++;
    	e[cnt].v=v;
    	e[cnt].next=p[u];
    	e[cnt].w=w;
    	p[u]=cnt;
    }
    void update(long long x){
    	if(!x) return;
    	for(int i=63;i>=0;i--){
    		if(x&(1ll<<i)){
    			if(a[i]) x^=a[i];
    			else{
    				a[i]=x;
    				return;
    			}
    		}
    	}
    }
    void dfs(int u,long long res){
    	vis[u]=1;
    	dis[u]=res;
    	for(int i=p[u];i!=-1;i=e[i].next){
    		int v=e[i].v;
    		if(vis[v]) update(res^e[i].w^dis[v]);
    		else dfs(v,res^e[i].w);
    	}
    }
    long long query(long long x){
    	for(int i=63;i>=0;i--){
    		if((x^a[i])>x) x^=a[i];
    	}
    	return x;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	memset(p,-1,sizeof(p));
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		int u,v;long long w;
    		cin>>u>>v>>w;
    		insert(u,v,w);
    		insert(v,u,w);
    	}
    	dfs(1,0);
    	cout<<query(dis[n]);
    	return 0;
    }
    
  • 相关阅读:
    AcWing 222 青蛙的约会
    AcWing 203. 同余方程
    AcWing 90. 64位整数乘法
    AcWing 89. a^b
    数论专题
    桌面软件开发框架大赏
    【Java/Oracle】利用user_tab_comments获取oracle表注释
    【Mybatis】使用结果嵌套方式完成一对多映射
    【MyBatis】一对一配置
    【java/Network】获得本机IP
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15474863.html
Copyright © 2020-2023  润新知