bzoj2115

线性基+dfs树

我们先搞出dfs树,其实最终路径就是最初的路径和一些环异或。

环最多只有m-n+1,因为一共有m条边,然后有n-1条边在dfs树上,所以还剩m-n+1条边,都可以构成环。

所以dfs搞出环,线性基找最大值就可以了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, ll> PII;
const int N = 200010;
int n, m, cnt;
vector<PII> G[N];
ll a[N], d[N];
int used[N];
void gauss()
{
    int now = 1;
    for(int i = 62; i >= 0; --i)
    {
        bool flag = false;
        for(int j = now; j <= cnt; ++j)
            if(a[j] & (1ll << i))
            {
                swap(a[j], a[now]);
                flag = true;
                break;
            }
        if(!flag) continue;
        for(int j = 1; j <= cnt; ++j) if((a[j] & (1ll << i)) && j != now)
            a[j] ^= a[now];
        ++now;
    }
    --now;
}
void dfs(int u, int last)
{
    used[u] = 1;
    for(int i = 0; i < G[u].size(); ++i)
    {
        PII x = G[u][i];
        int v = x.first;
        ll w = x.second;
        if(v == last) continue;
        if(!used[v])
        {
            d[v] = d[u] ^ w;
            dfs(v, u);
        }
        else a[++cnt] = d[v] ^ d[u] ^ w;
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    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);
    ll ans = d[n];
    gauss();
    for(int i = 1; i <= 62 && i <= cnt; ++i) if((ans ^ a[i]) > ans)
        ans ^= a[i];
    printf("%lld\n", ans);
    return 0;
} 

时间: 2024-10-11 22:36:28

bzoj2115的相关文章

【bzoj2115】 Xor

www.lydsy.com/JudgeOnline/problem.php?id=2115 (题目链接) 题意:给出一张图,可能有重边和自环,在图中找出一条从1-n的路径,使得经过的路径的权值的异或和最大,每条边可以重复经过并且重复计算异或和. Solution  刚看到这道题,想了10分钟完全没有思路,于是就膜了题解.  我们先把图看成一棵树,那么我们所需要找出的路径可以分成一些环和一条从1-n的树上路径,至于树是怎么构造的以及那条从1-n的路径是怎么走的并不重要,因为我们可以通过在总路径上补

BZOJ2115 [Wc2011] Xor

开始补冬令营期间做的题目啦~ 好吧冬令营ydl大爷在上面讲图的树分解,我们一帮二子在下面讨论这道题,讨论了2个小时2333 进入正题...首先我们把图dfs一遍,记录下这颗dfs的生成树 我们会发现,所有边分成了两种:树边和回边,并且不存在两棵子树之间有边. 定义回边和其中的树边形成的环叫基本环,则基本环最多有m - n个 然后题解上有一句话"不难发现,答案是由1到n号点的一条树链和几个基本环形成的",我去脑补半天啊!!!因为是xor所以来回路径上的边都算了两次刚好抵消掉. 于是题解君

BZOJ2115 WC2011 Xor DFS+高斯消元

题意:给定一张无向图,求1到N异或和最大的路径,允许重复经过. 题解:首先跑出1到N的一条路径,答案就是在这条路径上不断加环.首先用DFS处理出所有基环的异或和(其他环一定由基环构成,重复部分异或之后就会消掉),然后就是从一堆数里选任意个数使得异或和最小了,怎么做可以去看莫涛的课件(同解01异或方程),这里我简单介绍一下. 通过高斯消元,我们对原来的数进行操作,使得所有原来的数都可以用操作之后的数来组合而成(这玩意貌似叫线性基啊).具体做法就是从高到低暴力枚举每一位i,找到一个第i位为1的数j,

bzoj-2115 Xor

题意: 给出一个有权无向图: 求1到n的路径上的最大异或和. n<=50000,边权<=10^18. 题解: 因为异或的性质,我们能够知道对于随意一条连通图上的路径的异或和: 都能够由另外一条路径异或若干个环的异或和得来: 由于它们起点和终点都各自是1和n.那么这两个路本身就构成了一个可能经过同样边的环: 而更加显然的是.一个这种非简单环是能够由若干个简单环组成的: 那么异或了这些简单环之后得到了这个非简单环的异或和,再将原来的路径异或上去抵消掉,就是答案了: 所以处理出全部的简单环,和图中随

bzoj2115【WC2001】Xor

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 2059  Solved: 856 [Submit][Status][Discuss] Description Input 第一行包括两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描写叙述 M 条边,每行三个整数Si.Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包括一个整数,

【BZOJ-2115】Xor 线性基 + DFS

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2142  Solved: 893[Submit][Status][Discuss] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大

【bzoj2115】[Wc2011] Xor【高斯消元】

题目大意:给出一个无向有权图,找出一条从1到n的路径,使得路径上权值的异或和最大,路径可以重复走 Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大的XOR和(十进制结果) . Sample Input 5 71 2 21 3 22 4 12 5 14 5 35 3 44 3 2 Sample

【BZOJ2115】【Wc2011】 Xor 线性基 异或最长路

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43410545"); } 题意:找一条异或最长路. 题解:先随便来一条路径,然后我们发现这条路径上可以随便加简单环(不管有没有共点共边). 就是因为可以先从某点走到环上来一圈再走回来,这样来去的路径被搞没了,简直污得不行. 然后我们可以用线性基来决定去

[bzoj2115] [洛谷P4151] [Wc2011] Xor

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 想法 手动