zoukankan      html  css  js  c++  java
  • [bzoj 2115]线性基+图论

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2115

    给定一个带权无向图,要找出从1到n路径权值异或和最大的那一条的路径异或和。

    考虑1到n的任意一条路径,都可以表示为1到n的一条路径,加上图上任意的一些环(1所在的那个连通块)。之所以可以这样,是因为图是连通的,而且无向的,走过去也可以走回来,所以假设当前走到了i号点,我想去走一些环,那么可以i->j->在环j上走一圈->j->i,这条路径上仅仅是异或上了一次环的权值(i->j和j->i的权值被抵消了)。

    所以就把所有的环插入线性基就好了。最大值可以从高位到低位贪心来搞。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn=50005;
    const int maxm=100005*2;
    
    vector< pair<int,ll> > G[maxn];
    ll a[maxn];
    
    vector<ll> base;
    void insert(ll x)
    {
        for (int i=0;i<base.size();i++) x=min(x,x^base[i]);
        if (x) base.push_back(x);
    }
    
    void dfs(int u,int fa,ll now)
    {
        a[u]=now;
        for (int i=0;i<G[u].size();i++)
        {
            int v=G[u][i].first;
            ll w=G[u][i].second;
            if (a[v]==-1) dfs(v,u,now^w);
            else insert(now^a[v]^w);
        }
    }
    
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(a,-1,sizeof(a));
        for (int i=1;i<=m;i++)
        {
            int u,v;
            ll w;
            scanf("%d%d%lld",&u,&v,&w);
            G[u].push_back(make_pair(v,w));
            G[v].push_back(make_pair(u,w));
        }
        dfs(1,0,0);
        sort(base.begin(),base.end());
        ll ans=a[n];
        for (int i=base.size()-1;i>=0;i--) ans=max(ans,ans^base[i]);
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    vue-router路由器的使用
    组件间数据传递
    引用模块和动态组件
    vue自定义全局和局部指令
    vue实例的属性和方法
    vue生命周期以及vue的计算属性
    vue 发送ajax请求
    安装vue-cli脚手架
    vue指令详解
    scrapy-redis组件的使用
  • 原文地址:https://www.cnblogs.com/acmsong/p/7510026.html
Copyright © 2011-2022 走看看