You are given an undirected graph with weighted edges. The length of some path between two vertices is the bitwise xor of weights of all edges belonging to this path (if some edge is traversed more than once, then it is included in bitwise xor the same number of times). You have to find the minimum length of path between vertex 1 and vertex n.

Note that graph can contain multiple edges and loops. It is guaranteed that the graph is connected.

Input

The first line contains two numbers n and m (1 ≤ n ≤ 100000, n - 1 ≤ m ≤ 100000) — the number of vertices and the number of edges, respectively.

Then m lines follow, each line containing three integer numbers xy and w (1 ≤ x, y ≤ n, 0 ≤ w ≤ 108). These numbers denote an edge that connects vertices x and y and has weight w.

Output

Print one number — the minimum length of path between vertices 1 and n.

Examples

Input
3 3
1 2 3
1 3 2
3 2 0
Output
2
Input
2 2
1 1 3
1 2 3
Output

0

这是一个求从地点1到地点N经过路的异或和最短路的题;对于与一个环我们都可以使其异或和为零(一个环经过两次即异或和为0),一个环要么走完一遍,要么不走;我们可以任意找一条从1到N的路,然后异或每一个环,找最小值即可;

AC代码为:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
typedef long long LL;
int n,m,u,v,w,tot,temp,first[maxn],vis[maxn],a[maxn],b[maxn],dis[maxn];
struct Edge{
    int to,w,net;
} edge[maxn<<1];

inline void Init()
{
    memset(first,-1,sizeof first);
    memset(vis,0,sizeof vis);
    memset(b,0,sizeof b);
    tot=1;temp=0;
}

inline void addedge(int u,int v,int w)
{
    edge[tot].to=v;
    edge[tot].w =w;
    edge[tot].net=first[u];
    first[u]=tot++;
}

inline void dfs(int id,int len)
{
    vis[id]=1; dis[id]=len;
    for(int i=first[id];~i;i=edge[i].net)
    {
        if(vis[edge[i].to]) a[++temp]=dis[edge[i].to]^edge[i].w^len;
        else dfs(edge[i].to,len^edge[i].w);
    }
}

inline void Guass()
{
    for(int i=1;i<=temp;i++)
    {
        for(int j=31;j>=0;j--)
        {
            if((a[i] >> j) & 1)
            {
                if(!b[j])
                {
                    b[j]=a[i];
                    break;
                }
                else a[i]^=b[j];
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    Init();
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        addedge(u,v,w);
        addedge(v,u,w);
    }
    dfs(1,0);
    int ans=dis[n];
    for(int i=31;i>=0;i--) ans=min(ans,ans^b[i]);
    cout<<ans<<endl;
    return 0;
}

CodeForces845G-Shortest PathProblem?的更多相关文章

  1. [LeetCode] Encode String with Shortest Length 最短长度编码字符串

    Given a non-empty string, encode the string such that its encoded length is the shortest. The encodi ...

  2. [LeetCode] Shortest Distance from All Buildings 建筑物的最短距离

    You want to build a house on an empty land which reaches all buildings in the shortest amount of dis ...

  3. [LeetCode] Shortest Word Distance III 最短单词距离之三

    This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...

  4. [LeetCode] Shortest Word Distance II 最短单词距离之二

    This is a follow up of Shortest Word Distance. The only difference is now you are given the list of ...

  5. [LeetCode] Shortest Word Distance 最短单词距离

    Given a list of words and two words word1 and word2, return the shortest distance between these two ...

  6. [LeetCode] Shortest Palindrome 最短回文串

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  7. Leetcode: Encode String with Shortest Length && G面经

    Given a non-empty string, encode the string such that its encoded length is the shortest. The encodi ...

  8. LeetCode 214 Shortest Palindrome

    214-Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding ch ...

  9. POJ2001 Shortest Prefixes

    Description A prefix of a string is a substring starting at the beginning of the given string. The p ...

  10. Shortest Palindrome

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

随机推荐

  1. java多线程与线程并发四:线程范围内的共享数据

    当多个线程操作同一个共有数据时,一个线程对共有数据的改变会影响到另一个线程.比如下面这个例子:两个线程调用同一个对象的的方法,一个线程的执行结果会影响另一个线程. package com.sky.th ...

  2. PHP程序员-常用工具

    三连问 经常有社区的同学问: “我的PHP程序有没有阻塞,我的PHP程序有没有开启协程(对自己写好的代码表示不自信),我的PHP程序有没有问题”.然后贴出了自己的程序,然后进入了愉快的灌水环节,随着时 ...

  3. 领扣(LeetCode)单调数列 个人题解

    如果数组是单调递增或单调递减的,那么它是单调的. 如果对于所有 i <= j,A[i] <= A[j],那么数组 A 是单调递增的. 如果对于所有 i <= j,A[i]> = ...

  4. mysql注意:

    本例测试数据表 CREATE TABLE `test_student` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键自增id' ...

  5. usaco training <1.2 Your Ride Is Here>

    题面 Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often ...

  6. 使用Executor框架创建线程池

    Executor框架 Executor类:在java.util.concurrent类中,是JDK并发包的核心类. ThreadPoolExecutor: 线程池. Excutors: 线程池工厂,通 ...

  7. ubuntu server 1604 配置网络信息

    对于新安装的linux 服务器(ubuntu server 1604)   一,配置网络 连接网线与路由器 查看系统的网卡信息 ifconfig -a //列出所有的网卡信息,不管启用还是没有启用的 ...

  8. python进程池与线程池

    为什么会进行池化? 一切都是为了效率,每次开启进程都会分配一个属于这个进程独立的内存空间,开启进程过多会占用大量内存,系统调度也会很慢,我们不能无限的开启进程. 进程池原来大概如下图 假设有100个任 ...

  9. word使用指南(经常更新)

    一.快捷键 Ctrl+C 复制 Ctrl+X 剪切 Ctrl+V 粘贴 Ctrl+F 查找 Ctrl+A 全选 Ctrl+Z/Y 撤销/还原撤销 Ctrl+D 打开字体对话框 Ctrl+S 另存为 C ...

  10. 听说PHP的生成器yield处理大量数据杠杠的

    官方解释yield yield生成器是php5.5之后出现的,官方文档这样解释:yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大 ...