zoukankan      html  css  js  c++  java
  • 【BZOJ-2115】Xor 线性基 + DFS

    2115: [Wc2011] Xor

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 2142  Solved: 893
    [Submit][Status][Discuss]

    Description

    Input

    第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。

    Output

    仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。

    Sample Input

    5 7
    1 2 2
    1 3 2
    2 4 1
    2 5 1
    4 5 3
    5 3 4
    4 3 2

    Sample Output

    6

    HINT

    Source

    Solution

    线性基

    思路就是先随意一条路径,然后把每个环的存下来,求线性基,再与之前的路径取xor,取最大即为答案

    至于线性基,它的意义是:通过原集合S的某一个最小子集S1使得S1内元素相互异或得到的值域与原集合S相互异或得到的值域相同。

    然后XJB乱搞一下,具体写的比较明白的还是Oxer  折越

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    long long read()
    {
        long long x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 500010
    #define maxm 5000010
    int n,m,num;
    struct EdgeNode{int next,to;long long val;}edge[maxm<<1];
    int head[maxn],cnt;
    void add(int u,int v,long long w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].val=w;}
    void insert(int u,int v,long long w) {add(u,v,w); add(v,u,w);}
    bool visit[maxn];long long val[maxn],a[maxn];
    void DFS(int now)
    {
        visit[now]=1;
        for (int i=head[now]; i; i=edge[i].next)
            if (!visit[edge[i].to])
                val[edge[i].to]=val[now]^edge[i].val,DFS(edge[i].to);
            else a[++num]=val[edge[i].to]^edge[i].val^val[now];
    }
    int Gauss()
    {
        int tmp=1;
        for (int p=64; p>=0; p--)
            {
                int t=0;
                for (int j=tmp; j<=num; j++) if ((a[j]>>p)&1) {t=j;break;}
                if (t)
                    {
                        swap(a[t],a[tmp]);
                        for (int j=1; j<=num; j++) if (j!=tmp && ((a[j]>>p)&1)) a[j]^=a[tmp];
                        tmp++;
                    }
            }
        return tmp-1;
    }
    int main()
    {
        n=read(); m=read();
        for (int u,v,i=1; i<=m; i++) u=read(),v=read(),insert(u,v,read());
        DFS(1);
        long long ans=val[n];
        num=Gauss();
        for (int i=1; i<=num; i++) ans=max(ans,ans^a[i]);
        printf("%lld
    ",ans);
        return 0;
    }

    hsy大爷发题不写题解,程序还是hzwer的翻版

  • 相关阅读:
    legend3---videojs存储视频的播放速率便于用户观看视频
    legend3---mathjax的动态渲染问题解决
    matplotlib库疑难问题---10、画直方图
    matplotlib库疑难问题---9、画箭头(综合实例)
    js释放图片资源
    javascript中的原型与原型链
    前端跨域方式
    matplotlib清除 axes 和 figure
    matplotlib画直方图细解
    CentOS 7.8 安装 Python 3.8.5
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5517109.html
Copyright © 2011-2022 走看看