(线性基) bzoj 2115

2115: [Wc2011] Xor

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1258  Solved: 550
[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

求异或最长路啊,

 

首先随便找一条路,然后找环啊,判断环,用线性基啊

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<map>
using namespace std;
long long n,m,cnt;
vector<long long> w[250005];
vector<long long> e[250005];
bool vis[250005];
long long a[250005],ins[66],d[250005];
void dfs(int x)
{
    vis[x]=1;
    for(int i=0;i<e[x].size();i++)
    {
        int v=e[x][i];
        if(!vis[v])
            d[v]=d[x]^w[x][i],dfs(v);
        else a[++cnt]=d[v]^w[x][i]^d[x];
    }
}
void solve()
{
    for(int i=1;i<=cnt;i++)
    {
        for(int j=63;j>=0;j--)
        {
            if((a[i]>>j)&1)
            {
                if(!ins[j])
                {
                    ins[j]=a[i];
                    break;
                }
                else
                    a[i]^=ins[j];
            }
        }
    }
    long long ans=d[n];
    for(int i=63;i>=0;i--)
        if((ans^ins[i])>ans)
            ans=(ans^ins[i]);
    printf("%lld\n",ans);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        long long x,y,z;
        scanf("%lld%lld%lld",&x,&y,&z);
        e[x].push_back(y);
        e[y].push_back(x);
        w[x].push_back(z);
        w[y].push_back(z);
    }
    dfs(1);
    solve();
    return 0;
}

  

posted @ 2015-05-13 20:31  waterfull  阅读(132)  评论(0编辑  收藏  举报