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

    第二道线形基啊,开心

    开题的时候以为要用tarjan缩一遍图,然后在新图上,跑出一条简单路径,再把每个新点扔进线形基,就可以了

    码了80行忽然发现好像这样没法做,赶紧去上了个厕所冷静了一下,然后发现直接dfs就好了

    废话一堆

    首先,dfs整个图,用dis[]记录每个点的距离,vis[]记录是否到达过,若到达过证明是个环,扔进线形基里面就好了

    最后查询输出即可

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2e5+7;
    int m,n,k,cnt,head[N];
    ll dis[N];
    struct xxj
    {
        ll p[60];
        void insert(ll x)
        {
            for (int i=60;i>=0;i--)
            if (x&(1ll<<i))
            {
                if (!p[i]) {p[i]=x;break;} 
                else x^=p[i];
            }
        }
        ll query(ll x)
        {
            for (int i=60;i>=0;i--)
            x=max(x,x^p[i]);
            return x;
        }
    } G;
    struct edge
    {
        int nx,to;
        ll dist;
    } e[N];
    void add_edge(int a,int b,ll dist)
    {
        cnt++;e[cnt].to=b;e[cnt].nx=head[a];e[cnt].dist=dist;head[a]=cnt;
        cnt++;e[cnt].to=a;e[cnt].nx=head[b];e[cnt].dist=dist;head[b]=cnt;
    }
    bool vis[N];
    void dfs(int x)
    {
        vis[x]=true;
        for (int i=head[x];i;i=e[i].nx)
        {
            int y=e[i].to;
            if (!vis[y]) dis[y]=dis[x]^e[i].dist,dfs(y);
            else G.insert(dis[x]^dis[y]^e[i].dist);
        }
    }
    int main()
    {
        freopen("xorr.in","r",stdin);
        freopen("xorr.out","w",stdout);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            int x,y;
            ll z;
            scanf("%d%d%lld",&x,&y,&z);
            add_edge(x,y,z);
        }
        dfs(1);
        printf("%lld
    ",G.query(dis[n]));
        return 0;
    }
    慢即是快,细则是能,于小处铸迤逦
  • 相关阅读:
    eclipse工具
    Tag
    JSP模版
    Eclipse断点调试
    JavaBean
    验证码设计
    在IE中提示404错误
    序列化与反序列化
    文件编码问题
    强类型,弱类型和推断类型
  • 原文地址:https://www.cnblogs.com/Hale522520/p/10745478.html
Copyright © 2011-2022 走看看