zoukankan      html  css  js  c++  java
  • ACwing.228 异或(线性基)

    题目:

    • 给一张图,让你找一条1到n的路径,可以重复走边和点,问路径权值异或和最大是多少。

    题解:

    • 基本思路就是对每条路径把路径上的环的权值异或和放进线性基,因为环要走就走全部一次,走两次会异或掉。所以我们dfs找环,把环放进一个线性基,最后把1到n的简单路径异或和放进去,如果1到n有多个路径,就有环dfs就放进线性基中了,所以求最大值就好了。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<vector>
    #include<string>
    #include<fstream>
    
    
    using namespace std;
    typedef long long ll;
    const int N = 5e4 + 105;
    const int mod = 10000;
    const int P = 9999;
    const double Pi = acos(- 1.0);
    const int INF = 0x3f3f3f3f;
    
    
    inline int read() {
    	char ch = getchar(); int x = 0, f = 1;
    	while (ch < '0' || ch > '9') {
    		if (ch == '-') f = -1;
    		ch = getchar();
    	}
    	while ('0' <= ch && ch <= '9') {
    		x = x * 10 + ch - '0';
    		ch = getchar(); 
    	} return x * f;
    }
    
    //线性基
    const int maxbit = 62;		//maxbit不能太大
    
    struct L_B{
    	ll lba[maxbit];
    	int cnt;
    	L_B(){
    		memset(lba, 0, sizeof(lba));
    		cnt = 0;
    	}
    	
    	void Insert(ll val){		//插入
    		for(int i = maxbit - 1; i >= 0; -- i)
    			if(val & (1ll << i)){
    				if(!lba[i]){
    					lba[i] = val;
    					break;
    				}
    				val ^= lba[i];
    			}
    	}
    	
    
    	ll query_max(ll x){		//查找最大值
    		ll res = x;
    		for(int i = maxbit - 1; i >= 0; -- i){
    		    ll che = res ^ lba[i];
    			if(che > res) res^=lba[i];
    		}
    		return res;
    	}
    };
    
    //图论基本模板
    
    struct Edge{
    	int to;
    	ll c;
    	int nxt;
    }edge[N * 4];
    
    int head[N], cnt = 0;
    int n, m;
    
    inline void add(int u, int v, ll w){
    	edge[cnt].to = v;
    	edge[cnt].c = w;
    	edge[cnt].nxt = head[u];
    	head[u] = cnt ++;
    }
    
    //main()
    ll res;
    int vis[N];
    L_B lb;
    ll dis[N];
    
    void dfs(int u, int pre){
    	vis[u] = 1;
    	for(int i = head[u]; i != -1; i = edge[i].nxt){
    		int v = edge[i].to;
    		ll w = edge[i].c;
    		if(v == pre) continue;
    		if(vis[v]){
    			lb.Insert(w ^ dis[u] ^ dis[v]);
    			continue;
    		}
    		dis[v] = dis[u] ^ w;
    		dfs(v, u);
    	}
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	memset(head, -1, sizeof(head));
    	for(int i = 1; i <= m; ++ i){
    		int x, y;
    		ll w;
    		scanf("%d%d%lld",&x,&y,&w);
    		add(x, y, w);
    		add(y, x, w);
    	}
    	dfs(1, -1);
    	printf("%lld
    ",lb.query_max(dis[n]));
    	return 0;
    }
    
    
    
    
  • 相关阅读:
    Android Activity
    As3 3D学习之rotation
    Android学习之Android自带例子 ContactManager
    Android学习之 Menu
    Android学习之 Intent
    VC++学习之建立窗口
    As3 3D学习之屏幕与3D坐标
    Android学习之 Button onClickListener实现方法
    ClientDataSet 心得
    部分系统路径
  • 原文地址:https://www.cnblogs.com/A-sc/p/12791225.html
Copyright © 2011-2022 走看看