HDU 5544 Ba Gua Zhen dfs+高斯消元

Ba Gua Zhen

Problem Description

During the Three-Kingdom period, there was a general named Xun Lu who belonged to Kingdom Wu. Once his troop were chasing Bei Liu, he was stuck in the Ba Gua Zhen from Liang Zhuge. The puzzle could be considered as an undirected graph with N vertexes and M edges. Each edge in the puzzle connected two vertexes which were ui and vi with a length of wi. Liang Zhuge had great interests in the beauty of his puzzle, so there were no self-loops and between each pair of vertexes, there would be at most one edge in the puzzle. And it was also guaranteed that there was at least one path to go between each pair of vertexes.

Fortunately, there was an old man named Chengyan Huang who was willing to help Xun Lu to hack the puzzle. Chengyan told Xun Lu that he had to choose a vertex as the start point, then walk through some of the edges and return to the start point at last. During his walk, he could go through some edges any times. Since Liang Zhuge had some mysterious magic, Xun Lu could hack the puzzle if and only if he could find such a path with the maximum XOR sum of all the edges length he has passed. If the he passed some edge multiple times, the length would also be calculated by multiple times. Now, could you tell Xun Lu which is the maximum XORcircuit path in this puzzle to help him hack the puzzle?

Input

The first line of the input gives the number of test cases, T(1≤T≤30). T test cases follow.

Each test case begins with two integers N(2≤N≤5×104) and M(1≤M≤105) in one line. Then M lines follow. Each line contains three integers ui, viand wi(1≤ui,vi≤N,0≤wi≤260−1) to describe all the edges in the puzzle.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum XOR sum of one circuit path in the puzzle.

Sample Input

2
3 3
1 2 1
1 3 2
2 3 0
6 7
1 2 1
1 3 1
2 3 1
3 4 4
4 5 2
4 6 2
5 6 2

Sample Output

Case #1: 3
Case #2: 3

Hint

A XOR takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits.
The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1.
In this we perform the comparison of two bits, being 1 if the two bits are different, and 0 if they are the same.

题意:

  给你n个点m条边的无向图

  让你求一条回路使得经过每条路径权值异或和最大,求这个最大值

  路径可以多次经过

题解:

  画图可以发现

  把所有环挑出来,任意组合就好

  任意个数组合使得异或和最大,这特么就是个原题了

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e5+10, M = 1e3+20, mod = 1e9+7, inf = 2e9;

int head[N],t,cas = 1;
struct ss{
    int to,next;
    LL value;
}e[N*2];
int vis[N],cnt,T,n,m;
LL dep[N],ins[N],a[N];
void add(int u,int v,LL w) {
    e[t].next = head[u];
    e[t].to = v;
    e[t].value = w;
    head[u] = t++;
}
void dfs(int u,int f) {
    vis[u] = vis[f] + 1;
    for(int i = head[u]; i; i = e[i].next) {
        int to = e[i].to;
        if(to == f || (vis[to] && vis[to] < vis[u])) continue;
        if(vis[to]) {
            a[++cnt] = e[i].value ^ dep[to] ^ dep[u];
            continue;
        }
        dep[to] = dep[u] ^ e[i].value;
        dfs(to,u);
    }
}
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        memset(head,0,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(dep,0,sizeof(dep));
        memset(ins,0,sizeof(ins));
        t = 1;
        cnt = 0;
        for(int i = 1; i <= m; ++i) {
            int u,v;LL w;
            scanf("%d%d%I64d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        dfs(1,0);
        for(int i = 1; i <= cnt; ++i) {
            for(int j = 62; j >= 0; --j) {
                if(a[i]&(1LL<<j)) {
                    if(!ins[j]) {
                        ins[j] = a[i];
                        break;
                    }
                    a[i] ^= ins[j];
                }
            }
        }
        LL ans = 0;
        for(int i = 62; i >= 0; --i) {
            if((ins[i]^ans) > ans) ans^=ins[i];
        }
        printf("Case #%d: %I64d\n",cas++,ans);
    }
    return 0;
}
时间: 2024-08-23 10:10:18

HDU 5544 Ba Gua Zhen dfs+高斯消元的相关文章

hdu 3992 AC自动机上的高斯消元求期望

Crazy Typewriter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 391    Accepted Submission(s): 109 Problem Description There was a crazy typewriter before. When the writer is not very sober, it

BZOJ2115 WC2011 Xor DFS+高斯消元

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

BZOJ 2115 Wc2011 Xor DFS+高斯消元

题目大意:给定一个无向图,每条边上有边权,求一条1到n的路径,使路径上权值异或和最大 首先一条路径的异或和可以化为一条1到n的简单路径和一些简单环的异或和 我们首先DFS求出任意一条1到n的简单路径以及图中所有最简单的简单环(环上不存在两个点可以通过环外边直连) 然后在一些数中选出一个子集,使它们与一个给定的数的异或和最大,这就是高斯消元的问题了 利用高斯消元使每一位只存在于最多一个数上 然后贪心求解即可 #include<cstdio> #include<cstring> #in

hdu 5088 Revenge of Nim II(高斯消元)

题目链接:hdu 5088 Revenge of Nim II 题目大意:Nim游戏的变形,因为游戏很不公平,所以现在转变规则,后手可以选取若干堆石子剔除,剩下堆的石子用 来进行游戏,问说后手可能胜利吗. 解题思路:其实即为取出非0堆石子,使得Nim和为0.因为是Nim和(亦或),所以以每个位建立方程,列出40个方 程,进行亦或形式的高斯消元,因为全0肯定为一解,所以方程肯定有解,那么存在多解的情况即为存在自有变元. #include <cstdio> #include <cstring

HDU 3359 Kind of a Blur(高斯消元)

题意: H * W (W,H <= 10) 的矩阵A的某个元素A[i][j],从它出发到其他点的曼哈顿距离小于等于D的所有值的和S[i][j]除上可达点的数目,构成了矩阵B.给定矩阵B,求矩阵A. 题目先给宽再给高...坑我了一个小时 code /* 暴力确定每个位置有到那些位置的曼哈顿距离小于D 然后对你n*m个未知数,n*m个方程进行高斯消元 */ #include <iostream> #include <cstdio> #include <cmath> #

[ACM] hdu 2262 Where is the canteen (高斯消元求期望)

Where is the canteen Problem Description After a long drastic struggle with himself, LL decide to go for some snack at last. But when steping out of the dormitory, he found a serious problem : he can't remember where is the canteen... Even worse is t

HDU 5119 Happy Matt Friends(DP || 高斯消元)

题目链接 题意 : 给你n个数,让你从中挑K个数(K<=n)使得这k个数异或的和小于m,问你有多少种异或方式满足这个条件. 思路 : 正解据说是高斯消元.这里用DP做的,类似于背包,枚举的是异或的和,给定的数你可以选择放或者不放,dp[i][j]代表的是前 i 个数中选择k个异或的和为j. 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #define LL long long

HDU 5833 Zhu and 772002 (数论+高斯消元)

题目链接 题意:给定n个数,这n个数的素因子值不超过2000,从中取任意个数使其变成完全平方数,问有多少种取法. 题解:开始用素筛枚举写了半天TLE了,后来队友说高斯消元才想起来,果断用模板.赛后又得知这是个原题,真坑啊.把每个数进行素因子分解,素因子a的幂为奇数则视为1,偶数则视为0,转化为从n个数中取数异或和为0有多少种取法的问题. AC代码: #include <cstdio> #include <cstring> #include <cmath> #includ

Hdu 5833 Zhu and 772002(高斯消元解异或方程组)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5833 思路: 将每个数质因数分解,若该位质因数指数为偶数,则该位a[i]为0,否则该位a[i]为1(记a[i]为质因数分解后第i个质数所对应值). 合法方案为积的各位质因子个数对应值a[i]异或值为0. 例3=3^1,4=2^2,则3*3*4对应: 2           3 0   (1 xor 1=0) 则可列方程组 a11x1+a12x2+...+a1nxn=0 a21x1+a22x2+...