Upd2018.2.3
这题的话,显然地,答案就是随便选择一个路径,然后可以用图上所有的环
问题是怎么找出全部的环
先随便建立一个生成树,然后如果有返祖边就是一个环
但是这样并不可以找出所有的环,我以前就理解错了QAQ,也没有认真思考
至于剩下的环,一般就是环套环的话,里面有的环会找不到
但是这种环可以通过两个环xor起来得到
所以我们最后在线性基里面寻找答案的同时,也是在寻找最后的环的过程
原文
又是一个线性基。。
这题解题的关键就是这张图是双线边
所以对于一个环,只要他有价值都可以取到
因为去那里的路径走两次就消失了
接着我们只需要随便找一条路径,接着将全部环的异或值放入线性基内就可以了
至于为什么可以随便找路径呢?
因为要是有两条路可以到终点,那么他肯定是一个环啊,因为边都是是双向的
最后我们贪心取的时候肯定会更新到答案的
线性基真是伟大。。
code:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL N=50005;
const LL M=100005;
LL n,m;
struct qq
{
LL x,y,z,last;
}s[M*2];LL num,last[N];
void init (LL x,LL y,LL z)
{
num++;
s[num].x=x;s[num].y=y;s[num].z=z;
s[num].last=last[x];
last[x]=num;
}
bool vis[N];
LL f[N];
LL g[65];
void ins (LL x)
{
for (LL u=62;u>=0;u--)
if (x>>u&1)
{
if (g[u]==0) {g[u]=x;return ;}
x=x^g[u];
}
}
void dfs (LL x)
{
vis[x]=true;
for (LL u=last[x];u!=-1;u=s[u].last)
{
LL y=s[u].y;
if (vis[y]==false)
{
f[y]=f[x]^s[u].z;
dfs(y);
}
else ins(f[y]^f[x]^s[u].z);
}
}
LL get (LL x)
{
for (LL u=62;u>=0;u--)
if ((x^g[u])>x) x=x^g[u];
return x;
}
int main()
{
memset(g,0,sizeof(g));
memset(vis,false,sizeof(vis));
num=0;memset(last,-1,sizeof(last));
scanf("%lld%lld",&n,&m);
for (LL u=1;u<=m;u++)
{
LL x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
init(x,y,z);init(y,x,z);
}
dfs(1);
printf("%lld\n",get(f[n]));
return 0;
}