zoukankan      html  css  js  c++  java
  • [WC2011]最大XOR和路径(贪心+线性基)

    题目大意:给一张无向图,求一条1-n的路径,是路径边权的异或和最小。

    题解

    这道题的思路很妙,首先我们可以随便找出一条从1到n的路径来,然后我们可以选一些环。

    其实不管这个环和这条路径有怎样的关系,我们都是可以直接选的。

    比如说选了一个和这个路径没有交的环,等价于从1走到了这个环然后走了一圈又走回到了1,一条边被异或两次相当于吗,没走。

    对于和路径有交的环,异或上它相当于把有交的部分异或两次,相当于走了这个环,也是合法的。

    然后我们把所有环插入线性基中,预处理可以用dfs实现。

    代码

    #include<iostream>
    #include<cstdio>
    #define N 100002
    using namespace std;
    typedef long long ll;
    ll dis[N],tot,head[N],b[100],n,m;
    bool vis[N];
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    struct edge{int n,to;ll l;}e[N<<1];
    inline void add(int u,int v,ll l){e[++tot].n=head[u];e[tot].to=v;e[tot].l=l;head[u]=tot;}
    inline void ins(ll x){
        for(int i=62;i>=0;--i)if((1ll<<i)&x){
            if(b[i])x^=b[i];
            else{b[i]=x;return;}
        }
    }
    inline ll query(ll x){
        for(int i=62;i>=0;--i)if((b[i]^x)>x)x^=b[i];
        return x;
    }
    void dfs(int u){
        vis[u]=1;
        for(int i=head[u];i;i=e[i].n){
            int v=e[i].to;
            if(vis[v])ins(dis[u]^dis[v]^e[i].l);
            else dis[v]=dis[u]^e[i].l,dfs(v);
        }
    }
    int main(){
        n=rd();m=rd();ll u,v,w;
        for(int i=1;i<=m;++i){
            u=rd();v=rd();w=rd();
            add(u,v,w);add(v,u,w);
        }
        dfs(1);
        printf("%lld
    ",query(dis[n]));
        return 0;
    }
  • 相关阅读:
    【C#进阶系列】06 类型和成员基础
    纪中5日T1 1564. 旅游
    纪中17日T1 2321. 方程
    纪中17日T2 2322. capacitor
    纪中10日T1 2313. 动态仙人掌
    纪中14日听课小结 图论 最短路 二分图 差分约束
    一个抓猫的游戏 消遣GAME 持续更新中!
    洛谷P1464 Function  HDU P1579 Function Run Fun
    洛谷P1976 鸡蛋饼
    纪中12日T1 2307. 选择
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10160431.html
Copyright © 2011-2022 走看看